注册consumer节点-ZookeeperRegistry -doRegister
消费者启动时,会根据订单订阅的接口
在对应的节点下创建consumer节点
ZookeeperRegistry -doSubscribe
doSubscribe() 方法是订阅操作的核心实现
consumer://192.168.5.1/org.apache.dubbo.demo.DemoService?application=demo-consumer&category=providers,configurators,routers&check=false&dubbo=2.0.2&init=false&interface=org.apache.dubbo.demo.DemoService&methods=sayHello,sayHelloAsync&pid=9112&qos.port=33333&side=consumer&sticky=false×tamp=1596681445600
Protocol 为 consumer ,表示是 Consumer 的订阅协议,
其中的 category 参数表示要订阅的分类,这里要订阅 providers、configurators 以及 routers 三个分类;
interface 参数表示订阅哪个服务接口,这里要订阅的是暴露 org.apache.dubbo.demo.DemoService 实现的 Provider
175行左右
List<URL> urls = new ArrayList<>();
//根据url获取订阅的path
for (String path : toCategoriesPath(url)) {
//循环创建监听器
ConcurrentMap<NotifyListener, ChildListener> listeners = zkListeners.computeIfAbsent(url, k -> new ConcurrentHashMap<>());
ChildListener zkListener = listeners.computeIfAbsent(listener, k -> (parentPath, currentChilds) -> ZookeeperRegistry.this.notify(url, k, toUrlsWithEmpty(url, parentPath, currentChilds)));
zkClient.create(path, false);
List<String> children = zkClient.addChildListener(path, zkListener);
if (children != null) {
urls.addAll(toUrlsWithEmpty(url, path, children));
}
}
notify(url, listener, urls);
}
- toCategoriesPath
private String[] toCategoriesPath(URL url) {
String[] categories;
if (ANY_VALUE.equals(url.getParameter(CATEGORY_KEY))) {
categories = new String[]{PROVIDERS_CATEGORY, CONSUMERS_CATEGORY, ROUTERS_CATEGORY, CONFIGURATORS_CATEGORY};
} else {
categories = url.getParameter(CATEGORY_KEY, new String[]{DEFAULT_CATEGORY});
}
String[] paths = new String[categories.length];
for (int i = 0; i < categories.length; i++) {
paths[i] = toServicePath(url) + PATH_SEPARATOR + categories[i];
}
return paths;
}
最终返回3个path
通过 URL 中的上述参数,ZookeeperRegistry 会在 toCategoriesPath() 方法中将其整理成一个 ZooKeeper 路径,然后调用 zkClient 在其上添加监听。
provider节点,因为服务端已经创建这里加入容器即可
这里有个递归
创建完父节点,再创建
- 节点存在,异常被捕获了
@Override
public void createPersistent(String path) {
try {
client.create().forPath(path);
} catch (NodeExistsException e) {
//如果节点存在,只打印日志不做处理
logger.warn("ZNode " + path + " already exists.", e);
} catch (Exception e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
之后会依次创建
-
提供者 启动时,只会创建
configurators, providers, -
消费者启动时创建
consumers, routers