XXL-RPC框架分析
作者官方已经提供了比较完善的文档。算是比较简单易学的RPC框架。适合初学者学习。
一般一个完整的RPC架构四个核心的组件,分别是Client,Client Stub,Server,Server Stub,这个Stub可以理解为存根。
客户端(Client),服务的调用方。
客户端存根(Client Stub),存放服务端的地址消息,再将客户端的请求参数打包成网络消息,发送给服务方。在java中我们可以使用动态代理技术(Proxy,字节码技术也行),来生成代理对象,获取请求方法名字,参数等信息,封装起来
服务端(Server),真正的服务提供者。
服务端存根(Server Stub),接收客户端发送过来的消息,将消息解包,并调用本地的方法。使用java反射技术,对某个类的某个方法进行反射执行
支持多种序列号方案
主要包结构
类图:
配置
@XxlRpcReference
@XxlRpcService
ProviderFactory
bug:
XxlRpcSpringProviderFactory corePoolSize,maxPoolSize 默认大小要调整比如10,不然zk下会报错是bug
java.lang.NoClassDefFoundError: org/apache/zookeeper/Watcher 加入下面mvn配置
1 | <dependency> |
registry
服务发现与注册,包括zookeeper、LocalServiceRegistry(本地服务注册)、XxlRegistryServiceRegistry(作者写的注册中心)。可选组件,可不启用注册中心,直接指定服务提供方机器地址通讯
XXL-RPC中每个服务在zookeeper中对应一个节点,子节点类型为zookeeper的EPHMERAL类型,该类型节点有个特点,当机器和zookeeper集群断掉连接后节点将会被移除。consumer底层可以从zookeeper获取到可提供服务的provider集群地址列表,从而可以向其中一个机器发起RPC调用。如果使用zookeeper不要忘记引包
xxl-rpc-sample-springboot修改成zk的demo修改配置XxlRpcProviderConfig,XxlRpcInvokerConfig修改类似:
1 |
|
还有就是添加zookeeper maven配置
前面提到的XxlRpcSpringProviderFactory两个poolSize配置
remoting
服务提供者,服务调用者,网络通信
XxlRpcRequest 请求实体设计
requestId:唯一的标识,请求与响应对应,作者使用的uuid
createMillisTime:时间戳,主要是用于服务提供者进行超时检测用的
accessToken:用于服务调用者权限验证用的
className:需要调用的类的全类名
methodName:该类的方法名,服务调用者找到要执行的对象后就会invoke该方法
parameterTypes:方法参数类型数组
parameters:方法参数的值
version:服务提供着版本
XxlRpcResponse 响应实体设计
requestId:与XxlRpcRequest中的requestId一一对应,为的是异步的时候能找到对应的响应
errorMsg:错误信息,超时,权限验证失败
result:方法的执行结果
route 负载均衡算法
- XxlRpcLoadBalanceRandomStrategy 随机
- XxlRpcLoadBalanceRoundStrategy 轮询 使用次数%服务提供者的数量
- XxlRpcLoadBalanceLRUStrategy 最近使用最少
- XxlRpcLoadBalanceConsistentHashStrategy 一致性Hash:将所有提供该服务的机器按照hash值(节点)从小到大的顺序排列到hash环上,,然后计算出这个服务key的hash值,也按照循序放到hash环上,然后顺时针取挨着你最近的那个节点就行了 ,这样每次这个服务都去找这个节点
- LFU 最近访问频率低淘汰
serialize
列化功能
util
网络工具类
xxl-rpc-simple
服务提供者启动过程分析
大体流程: 收集配置→启动服务→服务注册
- XxlRpcService注解 version记录服务版本
- XxlRpcSpringProviderFactory spring的@Configuration配置类会创建该工厂,负责找出@XxlRPcService注解进行基础配置。
public class XxlRpcSpringProviderFactory extends XxlRpcProviderFactory implements ApplicationContextAware, InitializingBean,DisposableBean
实现ApplicationContextAware同时重写setApplicationContext(),setApplicationContext()中遍历注解调用addService()添加服务。 - XxlRpcSpringProviderFactory 还实现类InitializingBean接口,重写afterPropertiesSet方法,进行数据相关初始化序列化等相关,还调用了父类initConfig() ,start()通过请求配置的NeType进行启动服务,如果配置的是netty就会调用NettyServer start()
- 一般我们使用netty框架,然后调用onStarted方法,设置回调,回调函数把服务最终registry到注册中心(127.0.0.1:8888,127.0.0.1:9999)
服务请求过程
- client 去注册中心获取可用服务信息(192.168.38.2:7080),XxlRpcSpringInvokerFactory 配置调用信息,afterPropertiesSet()里调用 xxlRpcInvokerFactory.start();,start()里面再调用ZkServiceRegistry start() 进行xxlZkClient初始化,设置回调处理,新启线程定时refreshDiscoveryData 获取服务(192.168.38.2:7080)
- 调用XxlRpcSpringInvokerFactory.postProcessAfterInstantiation() 分析XxlRpcReferenceBean生成服务serviceKey, ReflectionUtils.doWithFields 处理Controller对象然后xxlRpcInvokerFactory.getServiceRegistry().discovery(serviceKeyList); 查询服务
- 浏览器访问client Controller接口,会调用 XxlRpcSpringReferenceBean中getObject()进行对象初始化 会调用 return xxlRpcReferenceBean.getObject() 里面再调用 client.asyncSend(finalAddress, xxlRpcRequest); 去调用服务端服务 服务端返回信息封装入XxlRpcResponse