当前位置: 首页 > news >正文

dubbo protocol port 消费者端_一、dubbo的注册中心以及服务注册源码剖析

一、整体设计

  dubbo整体设计以及调用用链路参照官网 http://dubbo.apache.org/zh-cn/docs/dev/design.html

二、dubbo的注册中心

  1、注册中心参照官网 http://dubbo.apache.org/zh-cn/docs/user/references/registry/introduction.html

  2、zk注册中心详解

2.1、目录结构

    +- dubbo

     +- com.demo.service.HelloService

     +- consumers

      +- consumer://192.168.1.102/com.demo.service.HelloService?application=dubbo-demo-annotation-consumer&category=consumers&check=false&dubbo=2.0.2&init=false&interface=com.lagou.service.HelloService***

     +- providers

      +- dubbo://192.168.1.102:20880/com.demo.service.HelloService?anyhost=true&application=dubbo-demo-annotation-provider&deprecated=false&dubbo=2.0.2***

     +- configuration

     +- routers

0e96fa809f61f72567716e05b433f733.png

     解释:

    (1)、在服务启动的时候dubbo会在zk的根目录下创建一个dubbo的目录

    (2)、dubbo跟节点下面是当前所拥有的接口名称,如果有多个接口,则会以多个子节点的形式展开

    (3)、每个服务下面又分别有四个配置项

      1)、consumers: 当前服务下面所有的消费者列表(URL)

      2)、providers: 当前服务下面所有的提供者列表(URL)
      3)、confifiguration: 当前服务下面的配置信息信息,provider或者consumer会通过读取这里的配置信息来获取配置
      4)、routers: 当消费者在进行获取提供者的时,会通过这里配置好的路由来进行适配匹配规则2.2、dubbo中的url
    从2.1中咱们不难发现,无论是服务提供者还是服务消费者,在注册中心zk中都是以url的形式进行保存以便进行资源定位,所以咱们来具体看一下dubbo中的url
    规则:protocol://host:port/path?key=value&key=value
    例子:参考2.1中的目录结构中的consumer或者producer
    (1)、对应源码(构造方法)

ad99b0eb86fade1b849a53f9f7161660.png


   (2)、主要组成部分
     1)、protocol: 协议,一般像我们的 provider 或者 consumer 在这里都是人为具体的协议
     2)、host: 当前 provider 或者其他协议所具体针对的地址,比较特殊的像 override 协议所指定的host就是 0.0.0.0 代表所有的机器都生效
     3)、port: 和上面相同,代表所处理的端口号     4)、path: 服务路径,在 provider 或者 consumer 等其他中代表着我们真实的业务接口     5)、key=value: 这些则代表具体的参数,这里我们可以理解为对这个地址的配置。比如我们 provider中需要具体机器的服务应用名,就可以是一个配置的方式设置上去
   (3)、dubbo中的URL与JAVA中的URL的区别
     1)、dubbo中的URL支持参数的动态增减

e7de7433b9d6fc32ce20c8cf88b1fafc.png

703a77e63e34e20a186c6484a17be708.png

0d2ca76a918f582663fe6091dad834fb.png

f22cd206451469436bd79c61f06238e1.png

    2.3、服务本地缓存

421a15e15c5b1a98605026a5204ad9f3.png

3e26d63a6bf356c36c35849cd9eaea90.png


  从上面两张图我们可以看到,服务提供者在启动的时候会主动将自己提供的服务注册到注册中心中,而服务消费者在启动的时候也会去注册中心中获取自己引用的服务列表到本地并保存到文件中,而且需要订阅对应的服务提供者节点。当服务提供者有信息变更的时候消费者会收到节点变更通知,进而获取最新服务列表跟新本地缓存文件。  
 Dubbo在服务引用过程中会创建registry对象并加载本地缓存文件,会优先订阅注册中心,订阅注册中心失败后会访问本地缓存文件内容获取服务提供信息
  下面我们来看一下具体的源码
  1)、顶级接口 org.apache.dubbo.registry.Registry

237b246522c0a7061387846b1415bde8.png

可以看到其中就提供了两个方法1、注册;2、注销。

74e7ab43475c2b32a192b23e6fade5a0.png


org.apache.dubbo.registry.RegistryService 这个类主要是对指定的路径进行注册,注销,监听和取消监听,查询操作。也是注册中心中最为基础的类
AbstractRegistry 是对注册中心的封装,其主要会对本地注册地址的封装,主要功能在于远程注册中心不可用的时候,可以采用本地的注册中心来使用
FailbackRegistry 失败自动恢复,后台记录失败请求,定时重发功能
接下来我们来看一下他的实现类org.apache.dubbo.registry.support.AbstractRegistry#AbstractRegistry的构造方法的具体实现

c731619c7b21b363192f7cae20fec352.png

3dca237ebedcdece9c9a092117cbe06e.png

fd7792be81f68fd087e6de8debc77865.png

8f888e7e95dd4b8c0b272d3ca16baaec.png

b897ff0339d25f5edf2396deb8766133.png

573101867f666498011e80d4b7bc3cb3.png

06cf7dc0ac1811e619caf52a959e513a.png


其实这里主要做的就是把url缓存到本地文件中 2.4、服务注册过程分析
1、服务注册时序图

a47b6cb57214f410667de287d2dbd3a0.png


    2、服务注册过程

ba9927c1a3d39bd53a4f1ff4a784aa94.png


说明:服务注册过程大致可以分为两个过程1、具体某个服务转换为Invoker,2、invoker转换成exporter
从上面两张图可以看出dubbo先从 ServiceConfig 类拿到对外提供服务的实际类 ref(如:HelloServiceImpl),然后通过ProxyFactory 接口实现类中的 getInvoker 方法使用 ref 生成一个 AbstractProxyInvoker 实例,到这一步就完成具体服务到 Invoker 的转化。接下来就是 Invoker 转换到 Exporter 的过程
那么是什么时候触发的服务注册呢?我们先来看一下org.apache.dubbo.config.ServiceConfig 的继承关系以及他的子类的继承关系我们就明白了

7a0ae7549b1d2a91011d069eeec6069c.png


从上图我们就可以发现,org.apache.dubbo.config.spring.ServiceBean继承了ServiceConfig而且实现了spring的一堆组件。熟悉spring的同学应该就知道了,在spring容器的生命周期中,这些组件都会进行初始化。
接下来我们重点看一下ServiceConfig中的ProxyFactory 和 Protocol 以及 ref 属性

ba0c537fa6b3259d2406c62f72be3309.png

48f9bb28e69a6540b15821249d0c3085.png


接下来我们再看一下协议接口

84fe1fbd07ecd5743fcddf6d97714167.png


可以看到协议顶级接口中提供了暴露和引用服务的接口它有很多实现类,而我们注册使用的是org.apache.dubbo.registry.integration.RegistryProtocol
接下来我们看一下如何将一个ServiceConfig转换成invoker由于方法较长就不详细截图了
org.apache.dubbo.config.ServiceConfig#export
org.apache.dubbo.config.ServiceConfig#doExport
org.apache.dubbo.config.ServiceConfig#doExportUrls
org.apache.dubbo.config.ServiceConfig#doExportUrlsFor1Protocol

c6c85eead259a1288370099e6d8e55fb.png


接下来我们再回头看看org.apache.dubbo.registry.integration.RegistryProtocol#export这个方法

0b8f7a664e15c18cb19601e913ca204f.png


这个方法呢主要做了5件事
1、获取注册中心的url:zookeeper://127.0.0.1:2181/org.apache.dubbo.registry.RegistryService?application=***
2、获取服务提供者的url: dubbo://192.168.1.102:20880/com.demo.service.HelloService?anyhost=**
3、获取注册中心
4、将服务提供者注册到注册中心中
5、返回暴露的对象
接下来我们再看一下org.apache.dubbo.registry.integration.RegistryProtocol.DestroyableExporter类

db153317cfeded5332d7326330c4115b.png


他主要提供了一个获取invoker的方法
我们再看一下注册方法

696057e7e2ebdadb5834203559bd5fe9.png


可以看到这里使用的是工厂模式获取的具体工厂,接下来我们再看一下注册中心的工厂接口

5574c001111eff9df3564e0247c57ee7.png


org.apache.dubbo.registry.RegistryFactory 是注册中心工厂,通过这种方式,也可以保证一个应用中可以使用多个注册中心。可以看到这里也是通过不同的protocol参数,来选择不同的协议
接下来我们看一下org.apache.dubbo.registry.support.FailbackRegistry#register

9d08ab6f5f9bd5d9a4819d1e15450eb8.png

24b3bb53f9ece6e57434a5e71d5d5059.png


这里主要做了三件事情
1、把当前url放入到已经注册的列表中
2、处理注册失败的url
3、真正处理当前url的注册
我们再看看真正处理当前url的注册方法就会发现这是一个模板方法,需要子类去提供具体实现

86ca62c3c5ecf2d5da594b688c248efe.png


既然dubbo默认使用zk为注册中心,那咱们就再看看zk的实现

262dd871dfc6284482a348d9839d303d.png


看到这里,服务注册的流程就ok了。

相关文章:

  • mysql事物捕捉异常回滚_事务场景中,手动捕获异常时记得显式回滚事务
  • mysql 不同版本多实例_MySQL 不同版本多实例
  • vue 时间刻度_一个基于Vue的时钟
  • arcgis数据导入mysql_jsp连接MySQL操作GIS地图数据实现添加point的功能代码
  • build vue3 后压缩的文件在哪_vue-cli脚手架之build文件夹三
  • window中mysql bat脚本_MySQL window环境下bat脚本定时备份
  • mybatis 字段名自动转小写_mybatis 返回Map类型key改为小写的操作
  • phppython混合开发_PHP资深开发者谈:缘何放弃PHP改用Python
  • python中init和new_Python中__init__和__new__的区别详解
  • lightgbm原理_LightGBM算法原理小结
  • mysql中以下正确的sql是_MySQL数据库中下面两句话的区别:
  • mysql安装需要jdkcheck_linux(center OS7)安装JDK、tomcat、mysql 搭建java web项目运行环境...
  • mysql模糊查询员工信息_PHP+MySQL实现模糊查询员工信息功能示例
  • mysql regexp_replace_mysql-使用DISTINCT的REGEXP_REPLACE
  • mysql 上周时间_mysql 获取上周1到周日的时间
  • php的引用
  • Date型的使用
  • iOS | NSProxy
  • javascript面向对象之创建对象
  • Java编程基础24——递归练习
  • linux安装openssl、swoole等扩展的具体步骤
  • Python代码面试必读 - Data Structures and Algorithms in Python
  • vue脚手架vue-cli
  • XML已死 ?
  • 对超线程几个不同角度的解释
  • 发布国内首个无服务器容器服务,运维效率从未如此高效
  • 浮动相关
  • 工作手记之html2canvas使用概述
  • 如何使用Mybatis第三方插件--PageHelper实现分页操作
  • 如何优雅地使用 Sublime Text
  • 体验javascript之美-第五课 匿名函数自执行和闭包是一回事儿吗?
  • 用简单代码看卷积组块发展
  • 远离DoS攻击 Windows Server 2016发布DNS政策
  • Linux权限管理(week1_day5)--技术流ken
  • shell使用lftp连接ftp和sftp,并可以指定私钥
  • ​软考-高级-信息系统项目管理师教程 第四版【第19章-配置与变更管理-思维导图】​
  • #NOIP 2014# day.1 生活大爆炸版 石头剪刀布
  • (5)STL算法之复制
  • (6)设计一个TimeMap
  • (SpringBoot)第七章:SpringBoot日志文件
  • (二)pulsar安装在独立的docker中,python测试
  • (二)windows配置JDK环境
  • (翻译)terry crowley: 写给程序员
  • (附源码)springboot社区居家养老互助服务管理平台 毕业设计 062027
  • (蓝桥杯每日一题)平方末尾及补充(常用的字符串函数功能)
  • (三)mysql_MYSQL(三)
  • (转)memcache、redis缓存
  • (转)母版页和相对路径
  • .Net Remoting(分离服务程序实现) - Part.3
  • .net安装_还在用第三方安装.NET?Win10自带.NET3.5安装
  • .NET简谈互操作(五:基础知识之Dynamic平台调用)
  • .NET下ASPX编程的几个小问题
  • .NET中GET与SET的用法
  • @Autowired @Resource @Qualifier的区别
  • [ C++ ] 继承