在上一篇文章Dubbo之服务暴露分析中介绍了当远程暴露时,如果有注册中心,需要在服务暴露后再将服务注册到注册中心。该篇将介绍该功能的有关步骤。

注册的起点

RegistryProtocol.export()方法包含了服务导出,注册,以及数据订阅等逻辑。其中服务注册先调用RegistryProtocol.register()方法。

public void register(URL registryUrl, URL registeredProviderUrl) {
// 获取 Registry
Registry registry = registryFactory.getRegistry(registryUrl);
// 注册服务
registry.register(registeredProviderUrl);
}

可以看出,服务注册主要包括两部分,获取注册中心实例向注册中心注册服务

获取注册中心实例

(1)调用registryFactory.getRegistry(registryUrl)方法,它会先访问缓存,缓存中不存在则调用createRegistry(URL)方法创建Registry,然后写入缓存。这里的createRegistry是一个模版方法,有具体的子类实现。这里假设使用zookeeper作为注册中心,则调用ZookeeperRegistryFactory的createRegistry()方法。

public Registry createRegistry(URL url) {
// 创建 ZookeeperRegistry
return new ZookeeperRegistry(url, zookeeperTransporter);
}
public ZookeeperRegistry(URL url, ZookeeperTransporter zookeeperTransporter) {
super(url);
if (url.isAnyHost()) {
throw new IllegalStateException("registry address == null");
} // 获取组名,默认为 dubbo
String group = url.getParameter(Constants.GROUP_KEY, DEFAULT_ROOT);
if (!group.startsWith(Constants.PATH_SEPARATOR)) {
// group = "/" + group
group = Constants.PATH_SEPARATOR + group;
}
this.root = group;
// 创建 Zookeeper 客户端,默认为 CuratorZookeeperTransporter
zkClient = zookeeperTransporter.connect(url);
// 添加状态监听器
zkClient.addStateListener(new StateListener() {
@Override
public void stateChanged(int state) {
if (state == RECONNECTED) {
try {
recover();
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
}
});
}

(2) 在ZookeeperRegistry构造方法中调用connect(url)方法,默认是CuratorZookeeperClient, 获得一个ZkClient客户端,之后添加状态监听器。

向注册中心注册服务

假设存在一个服务com.alibaba.dubbo.demo.DemoService, 那么 这个服务对应的配置信息(存储在 URL 中)最终被注册到了 /dubbo/com.alibaba.dubbo.demo.DemoService/providers/ 节点下。

(1) 调用FailbackRegistry.register()方法,之后调用里面的doRegister方法,它是一个模版方法,在ZookeeperRegistry中实现。

protected void doRegister(URL url) {
try {
// 通过 Zookeeper 客户端创建节点,节点路径由 toUrlPath 方法生成,路径格式如下:
// /${group}/${serviceInterface}/providers/${url}
zkClient.create(toUrlPath(url), url.getParameter(Constants.DYNAMIC_KEY, true));
} catch (Throwable e) {
throw new RpcException("Failed to register...");
}
}

(2) 调用create()方法。通过递归创建当前节点的上一级路径,然后再根据ephemeral的值决定是创建临时还是持久节点。分别调用createEphemeralcreatePersistent方法。

最新文章

  1. Intellij Idea 工具在java文件中如何避免 import .*包
  2. go语言让windows发出声音,或者播放音乐
  3. Effective c++
  4. java 23 - 3 单例模式实现Runtime类
  5. 使用VB6制作RTD函数
  6. 第五篇:python高级之面向对象高级
  7. 对html制作新手的一些建议,大牛可以忽略
  8. EasyUI - 使用一般处理程序 HttpHandler (.ashx)
  9. jmeter(八)-JDBC请求(sqlserver)
  10. VMWare下ubuntu无法全屏的问题解决
  11. 基于IndexedDB实现简单文件系统
  12. Python 自动化 第一周
  13. Center a website:网页居中
  14. 给video添加自定义进度条
  15. oracle里实例和数据库之间的关系
  16. maven开发项目中遇到的问题
  17. html网页练习豆瓣网
  18. PostgreSQL的SQL语句中的双引号引发的问题
  19. Python-pycurl模块的安装
  20. 金蝶盘点机PDA仓库条码管理:仓库如何盘点

热门文章

  1. 向C++之父Bjarne Stroustrup致敬
  2. JMeter接口测试-提取动态列表最后一个值的两种方法
  3. WebSocket协议分析
  4. nginx+uwsgi部署Django项目到Ubuntu服务器全过程,以及那些坑!!!
  5. F12后面的世界(Elements篇)——重识html
  6. 08.JS单词整理
  7. SpringCloud之Ribbon负载均衡的入门操作
  8. 【python数据挖掘】爬取豆瓣影评数据
  9. vue中this在回调函数中的使用
  10. 常用Content-type对照表