RPC Client && RPC Server
RPC Client
1、动态代理,根据lookUp信息(接口-实现-方法)动态创建出代理类,(创建代理类==RPC服务端的目标接口)。即Lookup为远端目标接口地址,创建调用目标接口代理。
2、上下文管理,主要为标识每个请求的sessionID,保证server端返回的结果找到对应的上下文。例如同时ABC三个请求从客户端发送到server去请求,上下文就用来标识server返回的ABC response对应客户端发来的ABC request。
处理好client的请求数据后,经过序列化、经由两端统一的协议,传输到server端,进行反序列化操作解析出目标接口、参数等信息,执行invoke调用后,将结果再次序列化传输。
RPC Server
1、分发器,将请求分发到sever实例(负载策略&容错)
2、过滤器,统一拦截,在server方法执行前后进行链路调用统计、超时统计等操作
3、线程模型,下面深入总结:
核心流程
1、创建接口代理类:从客户端开始,利用动态代理创建server目标接口代理
2、序列化:将入参对象序列化
3、协议组装:将序列化方式、协议版本、协议类型、方法签名等信息组装成一个协议包,交付给传输层进行发送
4、传输,server协议:传输层将协议包发送到sever端,server端将协议包解析,从中取出接口签名、入参对象字节流信息
5、server反序列化:反序列化操作,找出接口实现类(server端真实的服务实现),invoke执行目标方法
6、server将结果序列化:Server端将返回结果按照同样的序列化方式进行序列化操作。
7、server组装协议:同样,将序列化方式、协议版本、协议类型、方法签名等信息组装成一个协议包,发送给client
8、client解析协议,反序列化结果:Client接收sever返回的协议包,经过解析协议包中返回结果流,反序列化操作,得到RPC方法调用结果
完整的一个RPC请求流程 (provider、consumer、zk注册中心这这个是应用层的事情,不是rpc底层)
从RPC架构和流程不难看出,RPC核心技术包括:动态代理、序列化、协议、通讯(netty)、注册中心几块技术。动态代理就不多说了,可见下一篇博文:JDK、CGLib、Javassist实现动态代理。本次重点讨论序列化反序列化、传输协议、server端的线程模型。
序列化载体:
xml:可扩展标记语言,自定义节点schema含义;但传输太多额外无用的数据(schema、节点解析)
Json:kv结构,易扩展
二进制字节流:紧凑,无额外多余数据,减少传输占用带宽;但字节顺序是固定的,例如user对象,1-8字节存储userId,8-16存储username;如果删减user属性,序列化反序列化时数据则对不上。则需要对属性添加tagId标识,tagID(sortedId)=1,则标识userId,tagId=2标识username;type标识属性类型(类型可知则知道对应占字节长度),value标识属性值;(其实这里用tagID标识属性名,根据属性名采用反射即可得到字段类型、长度信息;可能考虑效率,直接采用key标识)
这就定义好了采用字节流来序列化传输对象。
常用的通讯协议、数据传输格式、底层传输协议、序列化方式、应用实现整理如下:
而项目中用的是restTemplate,(这里重点说一下它的LTS协议)
它是一个用于调用RESTful服务的java客户端库,它支持http和https协议。当使用https协议时,RestTemplate会使用TLS(transport layer security)协议来进行安全通讯。
TLS协议是一个加密协议,用于确保客户端和服务器之前的通信是安全的,它提供了认证、加密和数据完整性保护等功能,防止敏感数据被篡改或者窃听。
在使用RestTemplate进行https通信时,需要注意以下几点:
1、配置TLS版本:可以通过设置系统属性‘javax.net.ssl.keyStore’和’javax.net.ssl.keyStorePassword’,或者通过RestTemplate的‘DefaultUriBuilderFactory’来配置TLS八本。例如,可以使用以下代码配置TLS版本为TLSv1.2;
‘’‘java
System.setProperty(“https.protocols”,“TLSv1.2”);
‘’’
2、验证服务器证书:RestTemplate会默认验证服务器的证书,可以通过设置‘SimpleClientHttpRequestFactory’的‘setHostnameVerifier’方法来自定义证书验证逻辑。例如,可以使用以下代码跳过证书验证;
‘’’java
SumpleCilentHttpRequestFactory factory = new SumpleCilentHttpRequestFactory ();
factory.setHostnameVerifier((hostname.session) -> true);
RestTemplate restTemplate = new RestTemplate (factory);
‘’’
3、使用受信任的证书:如果服务器使用的是自签名或者由私有CA颁发的证书,需要将服务器的证书导入到Java的信任库中。可以使用keytool命令将证书导入信任库,然后代码中指定信任库的路径。例如,可以使用以下代码指定信任库的路径:
‘’’java
System.setProperty(“javax.net.ssl.trustStore”,“/path/to/your/truststore”);
System.setProperty(“javax.net.ssl.trustStorePassword”,“your_password”);
‘’’
通过以上配置,就可以使用RestTemplate进行https请求,并通过TLS协议进行加密和认证。
https://blog.csdn.net/Daybreak1209/article/details/80509964