背景
RPC(Remote Procedure Call Protocol,远程过程调用),调用远程服务就像调用本地服务,在提供远程调用能力时不损失本地调用的语义简洁性;
一般公司,尤其是大型互联网公司内部系统由上千上万个服务组成,不同的服务部署在不同机器,跑在不同的JVM上,此时需要解决两个问题:
- 1、如果我需要依赖别人的服务,但是别人的服务在远程机器上,我该如何调用?
- 2、如果其他团队需要使用我的服务,我该怎样发布自己的服务供他人调用?
“XXL-RPC”可以高效的解决这个问题:
- 1、如何调用:只需要知晓远程服务的stub和地址,即可方便的调用远程服务,同时调用透明化,就像调用本地服务一样简单;
- 2、如何发布:只需要提供自己服务的stub和地址,别人即可方便的调用我的服务,在开启注册中心的情况下服务动态发现,只需要提供服务的stub即可;
客户端(Client): 服务的调用方。
服务端(Server):真正的服务提供者。
客户端Stub:存放服务端的地址消息,再将客户端的请求参数打包成网络消息,然后通过网络远程发送给服务方。
服务端Stub:接收客户端发送过来的消息,将消息解包,并调用本地的方法。
Stub封装了远程调用的一些细节,使开发者进行远程调用的时候,就像调用本地接口一样。
![](https://img2020.cnblogs.com/blog/1341698/202106/1341698-20210616210007717-991412935.png)
客户端stub
代码位置参考(可在idea中全局搜索)
服务注册与发现 :
每隔10s钟服务就会像注册中心注册一下,用来更新updateTime
参考代码: boolean ret = registryBaseClient.registry(new ArrayList<XxlRpcAdminRegistryDataParamVO>(registryData));
心跳检测:不断更新updateTime,与当前时间差距30S就会删除:
参考代码:xxlRpcRegistryDataDao.cleanData(registryBeatTime * 3);
服务发现是在客户端本地发现的,
参考代码:invokerFactory.getRegister().discovery(serviceKey);
会有轮询去请求注册中心,更新本地缓存 如服务被禁用(discoveryData) 且注册中心从文件xxl.rpc.registry.data.filepath中拿,会有线程维护文件和db的一致性
参考代码:com.xxl.rpc.core.registry.impl.xxlrpcadmin.XxlRpcAdminRegistryClient#refreshDiscoveryData
检查注册中心数据 不断的从本地队列拿数据registryQueue.take();去check注册中心的数据
参考代码:checkRegistryDataAndSendMessage(xxlRpcRegistryData);
负载均衡 finalAddress = loadBalance.xxlRpcInvokerRouter.route(serviceKey, addressSet);
发送请求 clientInstance.asyncSend(finalAddress, xxlRpcRequest);
序列化 byte[] requestBytes = serializer.serialize(xxlRpcRequest);
服务端stub
反射调用代码位置参考(可在idea中全局搜索)
// invoke + response
XxlRpcResponse xxlRpcResponse = xxlRpcProviderFactory.invokeService(xxlRpcRequest);
// response serialize
byte[] responseBytes = xxlRpcProviderFactory.getSerializerInstance().serialize(xxlRpcResponse);
引用
源码地址:https://gitee.com/xuxueli0323/xxl-rpc?_from=gitee_search