Redis注册中心也沿用了Dubbo抽象的root、service、type、url四层结构。但是由于redis属于noSql数据库,数据都是用k-v形式保存的,并不能像zookeeper一样实现树状的目录结构。因此redis使用key/map结构实现这个需求,root、service、type组合形成redis的key,redis的value是一个map结构,url作为map的key,超时时间作为map的value。
数据结构的组装逻辑在RedisRegistry.doRegistry(url)方法中。
String key = toCategoryPath(url); //生成rediskey
String value = url.toFullString();//生成URL
Jedis.hset(key,value,expire); //注册到注册中心,expire为超时时间。
服务订阅与发布Zookeeper的实现
1、发布的实现
服务提供者和消费者都需要把自己注册到注册中心,服务提供者的注册是为了让消费者感知到服务的存在,也让服务治理中心感知其存在,消费者发布是为了让服务治理中心发现自己,zookeeper的发布代码非常简单,只是调用了zookeeper客户端在注册中心上创建一个目录。
ZkClient.create(toUrlPath(url));
Url.getParameter(Constants.DYNAMIC_KEY,true);
取消发布则直接删除zk中的路径即可。
ZkClient.delete(toUrlPath(url));
2、订阅的实现
订阅通常有pull和push两种方式,一种是客户端定时轮询注册中心的拉取配置,另一种是注册中心主动推送配置到客户端。这两种方式各有利弊,目前dubbo采用的是第一次启动拉取的方式,后续接受事件重新拉取数据。
在服务暴露时,服务端会订阅configurators用户监听动态配置,在消费端启动后,消费端会订阅providers、routers、configurators这三个目录,分别对应服务提供者,路由和动态配置变动通知。
Dubbo在dubbo-remoting-zookeeper模块中实现了zookeeper客户端的统一封装,定义了统一的client api,并用两种不同的zookeeper开源客户端库实现了这个接口。
Apache curator、zkClient
我们可以在中的client属性中设置curator、zkclient来使用不同的客户端实现库,如果不设置,默认为curator作为实现。
Zookeeper注册中心采用事件通知+客户端拉取的方式,客户端在第一次连接到注册中心的时候会拉取对应目录下的所有全量数据,并在订阅的节点上注册一个watcher,客户端与注册中心之间保持tcp长连接,后续每个节点有任何数据变化的时候注册中心会根据watcher的回调通知客户端,客户端收到通知后,悔吧对应节点下的全量数据拉取过来,这点在notifyListenner.notify上有说明。
周二愉快❤️