前言
本文是对Java开发者的RPC实战课的一个读后总结笔记,里面的代码均来自这里,有兴趣可以自行购买阅读
总体流程图
核心要点
注册中心引入后,客户端的订阅,以及服务端的暴露都是要借助注册中心来实现;总结下需要解决下面几个问题:
注册中心选取- zookeeper
当客户端,通过服务名查询服务提供者的url时(可能有多个);需要一个map的结构来供查询,本地缓存可以用hashmap,远方存储的话,zookeeper是个合适的选择;其中node和叶子结点的设计很符合我们的需求
服务暴露
服务端启动时,需要将自己的url(ip\port),注册到注册中心,即写到zookeeper,这样才能查到
服务订阅
客户端启动时,需要订阅注册中心;一个需要拉取servicename对于的url列表,放到本地缓存;还需要将自身注册,这样服务方发生变更时,好通知更新本地缓存
服务变更监听
就是刚刚提到的,服务端发生下线、上线的话;如何通知到客户端更新本地缓存;这个监听机制如何实现
- 利用,zookeeper的监听机制;获取到新的url列表
zkClient.watchChildNodeData(newServerNodePath, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
System.out.println(watchedEvent);
String path = watchedEvent.getPath();
List<String> childrenDataList = zkClient.getChildrenData(path);
URLChangeWrapper urlChangeWrapper = new URLChangeWrapper();
urlChangeWrapper.setProviderUrl(childrenDataList);
urlChangeWrapper.setServiceName(path.split("/")[2]);
IRpcEvent iRpcEvent = new IRpcUpdateEvent(urlChangeWrapper);
IRpcListenerLoader.sendEvent(iRpcEvent);
//收到回调之后在注册一次监听,这样能保证一直都收到消息
watchChildNodeData(path);
}
});
-
为了方便解耦,发送event,在listener中去做;并且在client启动时,会往listener列表中添加一个。然后遍历执行listener中的callback逻辑即可
-
在callback中执行替换urllist的操作
对比
咱们对比下引入注册中心后的不同点
- 发送消息时,获取channelFuture的方式;直接直接通过ip+端口号new;现在通过服务名随机从provider列表中获取(伪负载均衡)
- 服务启动时,需要将自己注册到注册中心
- 服务的下线,需要通知客户端,更新本地缓存
剩下的问题
服务下线,上面提到的是通过调用api的形式通知zookeeper,但是服务宕机时不会调用的,所以需要心跳机制来保活