发表于: 2020-06-19 23:34:01

1 4006


1.部署两台Service,如何在WEB中随机访问任意一台Service?  


通过在代码中生成随机数,来实现访问任意一台Services。

int index = (int) Math.floor((Math.random() * (2)));



2.RMI的简单介绍

RMI全称是remote method invocation 远程方法调用,一种用于远程过程调用的应用程序编程接口,是纯java的网络分布式应用系统的核心解决方案之一。


RMI使用Java远程消息交换协议JRMP(Java Remote Messaging Protocol)进行通信,JRMP是专门为Java对象制定的,对非Java语言开发的应用系统支持不足,不能与非java语言的对象进行通信

3.什么是RMI,什么是RPC,两者之间的区别是什么?  


RPC(远程过程调用)和RMI(远程方法调用)是两种可以让用户从一台电脑调用不同电脑上面的方法的的机制(也可以称作规范、协议)。两者的主要不同是他们的使用方式或者称作范式,RMI使用面向对象的范式,也就是用户需要知道他调用的对象和对象中的方法;RPC不是面向对象也不能处理对象,而是调用具体的子程序。


 一次RPC调用的过程大概有10步:


1.执行客户端调用语句,传送参数
2.调用本地系统发送网络消息
3.消息传送到远程主机
4.服务器得到消息并取得参数 
5.根据调用请求以及参数执行远程过程(服务)
6.执行过程完毕,将结果返回服务器句柄
7.服务器句柄返回结果,调用远程主机的系统网络服务发送结果
8.消息传回本地主机 
9.客户端句柄由本地主机的网络服务接收消息
10.客户端接收到调用语句返回的结果数据

RMI远程调用步骤:


1,客户调用客户端辅助对象stub上的方法
2,客户端辅助对象stub打包调用信息(变量,方法名),通过网络发送给服务端辅助对象skeleton
3,服务端辅助对象skeleton将客户端辅助对象发送来的信息解包,找出真正被调用的方法以及该方法所在对象
4,调用真正服务对象上的真正方法,并将结果返回给服务端辅助对象skeleton
5,服务端辅助对象将结果打包,发送给客户端辅助对象stub
6,客户端辅助对象将返回值解包,返回给调用者
7,客户获得返回值

参考: https://www.cnblogs.com/ygj0930/p/6542811.html


4.Service和Service之间可以互相调用吗?是应该统一Controller调用Service,还是应该Service调用Service? 


可以    但不符合规范    应该统一Controller调用Service


5.Service对外暴露的接口粒度应该是怎么样的,是只提供基础的CRUD服务,还是应该将业务逻辑包含进去? 


最好只提供crud服务, 具体的业务逻辑交给controller层来控制


6.Thrift,Protobuffer分别是什么,一般用于什么场景?


Thrift

是一种接口描述语言和二进制通讯协议,它被用来定义和创建跨语言的服务。

它被当作一个远程过程调用(RPC)框架来使用, 是由Facebook为“大规模跨语言服务开发”而开发的。它通过一个代码生成引擎联合了一个软件栈,来创建不同程度的、无缝的跨平台高效服务,可以使用C#C++(基于POSIX兼容系统)、Cappuccino、CocoaDelphiErlangGoHaskellJavaNode.jsOCamlPerlPHPPythonRubySmalltalk


Protocol Buffer

是一种支持多平台、多语言、可扩展的的数据序列化机制,相较于XML来说,protobuf更小更快更简单,支持自定义的数据结构,用protobu编译器生成特定语言的源代码,如C++、Java、Python,目前protoBuf对主流的编程语言都提供了支持,非常方便的进行序列化和反序列化。


Thrift的适用场景

对于需求为高性能,分布式的 RPC 服务,Thrift 支持众多语言和丰富的数据类型,并对于数据字段的增删具有较强的兼容性,所以非常适合公司内部 SOA 的标准 RPC 框架


Thrift的适用场景

Protobuf 具有广泛的用户基础,空间开销小一级高解析性是其亮点,非常适合于公司内部的对性能要求高的 RPC 调用。Protobuf 提供了标准的 IDL 以及对应编译器,其 IDL 文件是参与各方的非常强的业务约束,另外,Protobuf 与传输层无关,采用 Http 具有良好的跨防火墙的访问属性。由于其解析性能好,序列化后数据量相对少,非常适合应用层对象的持久化场景。

7.什么是序列化和反序列化,在RMI中是否要实现 Serializable 接口, serialVersionUID的用处是什么? 

 

序列化:把对象转换为字节序列的过程称为对象的序列化。

反序列化:把字节序列恢复为对象的过程称为对象的反序列化。


什么情况下需要序列化:
当你想把的内存中的对象状态保存到一个文件中或者数据库中时候;
当你想用套接字在网络上传送对象的时候;

当你想通过RMI传输对象的时候;


serialVersionUID的用处是什么?  


Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。


在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。


serialVersionUID有两种显示的生成方式: 一个是默认的1L,比如:private static final long serialVersionUID = 1L; 一个是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段


8.Controller通过RMI调用服务是否有延迟?10条Long型的ID循环调用1000次,和本地调用之间的时间相差多少? 


通过网络服务调用远程接口肯定有延迟(网络因素占主要)  

就像nginx调用tomcat  一样,中间也会有一些延迟  虽然很短


任务8总结:


一 脑图分析

二  任务中遇到哪些疑难问题,最终是如何解决的,有哪些值得分享的收获
1.先搞懂Java Rmi    再结合Spring完成Rmi的调用
2.整个流程:
(1)先把Spring服务端打包成一个单独的jar包
(2)在服务器运行jar包,启动服务端
(3)把Spring客户端打包成一个单独的war
(4)把war部署进服务器tomcat  运行,然后调用远程服务端
3.服务端打包jar的方式请选择 maven -shade-plugin

4.客户端没有业务  也要带上服务端的实体类  和  接口。



搭建一个springboot项目



controller类最好在  springbootApplication所属包下面


属性配置可以是两种

properties

或者
yml


controller文件可以直接取出yml的属性


启动spring boot

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class })
public class SpringbootoneApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootoneApplication.class, args);
}


spring内置tomcat的端口是8080     我配置文件改成了8081




搭建springboot+mybatis


配置文件需要加上这两个依赖
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
</dependencies>
student
package com.ptteng.springbootone.enity;
import org.springframework.stereotype.Component;
import java.io.Serializable;
//省略get set
public class student implements Serializable {
private Byte id;
private String img;
private String name;
private String introduce;
private Long salary;
private Long createAt;
private String createBy;
private Long updateAt;
private String updateBy;
private Byte proId;
}
studentMapper
public interface studentMapper {
List<student> allStudent();
}
studentMapper.xml    需放在resources下
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.ptteng.springbootone.mapper.studentMapper" >
<resultMap id="BaseResultMap" type="com.ptteng.springbootone.enity.student" >
<id column="id" property="id" jdbcType="TINYINT" />
<result column="img" property="img" jdbcType="VARCHAR" />
<result column="name" property="name" jdbcType="VARCHAR" />
<result column="introduce" property="introduce" jdbcType="VARCHAR" />
<result column="salary" property="salary" jdbcType="BIGINT" />
<result column="create_at" property="createAt" jdbcType="BIGINT" />
<result column="create_by" property="createBy" jdbcType="VARCHAR" />
<result column="update_at" property="updateAt" jdbcType="BIGINT" />
<result column="update_by" property="updateBy" jdbcType="VARCHAR" />
<result column="pro_id" property="proId" jdbcType="TINYINT" />
</resultMap>
<sql id="Base_Column_List" >
id, img, name, introduce, salary, create_at, create_by, update_at, update_by, pro_id
</sql>
<select id="allStudent" resultMap="BaseResultMap" >
select
<include refid="Base_Column_List" />
from student
</select>
</mapper>
studentService
public interface studentService {
List<student> allStudent();
}
studentServiceImpl
@Service(value = "studentService")
public class studentServiceImpl implements studentService {
@Autowired
studentMapper studentMapper;
@Override
public List<student> allStudent() {
return studentMapper.allStudent();
}
}
配置文件application.yml
server.port: 8081
spring:
datasource:
username: root
password: 451976
driver-class-name: com.mysql.jdbc.Driver
mybatis:
mapper-locations: classpath:mapping/*Mapper.xml
type-aliases-package: com.ptteng.springbootone.enity
启动项 SpringbootoneApplication
@SpringBootApplication
@MapperScan("com.ptteng.springbootone.mapper")//将项目中对应的mapper类的路径加进来就可以了
public class SpringbootoneApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootoneApplication.class, args);
}
}


查询成功


发现的其他东西: 


yml文件的在线编辑 解析(自动报错yml格式问题)

http://www.bejson.com/validators/yaml_editor/



springboot   


serviceimpl 引入 studentMapper 
爆红线  

解决方法:  https://blog.csdn.net/zyf2333/article/details/78105500



明天计划的事情:


springCloud








返回列表 返回列表
评论

    分享到