三、Dubbo 注册中心
3.1 注册中心概述
- 主要作用
- 动态加入:服务提供者通过注册中心动态地把自己暴露给其他消费者
- 动态发现:消费者动态地感知新的配置、路由规则和新的服务提供者
- 动态调整:注册中心支持参数的动态调整,新参数自动更新到所有相关服务节点
- 统一配置:避免本地配置导致每个服务的配置不一致问题
- 工作流程
- 服务提供者启动时,会向注册中心写入自己的元数据信息,同时会订阅配置元数据信息
- 消费者启动时,也会向注册中心写入自己的元数据信息,并订阅服务提供者、路由和配置元数据信息
- 服务治理中心(dubbo-admin)启动时,会同时订阅所有消费者、服务提供者、路由和配置元数据信息
- 当有服务提供者离开或有新的服务提供者加入时,注册中心服务提供者目录会发生变化,变化信息会动态通知给消费者、服务治理中心
- 当消费方发起服务调用时,会异步将调用、统计信息等上报给监控中心(dubbo-monitor・simple)
- 数据结构
- 不同的注册中心有不同的实现方式。其数据结构也不相同、
- ZooKeeper 原理概述
- 树形结构的注册中心,每个节点类型分为持久节点、持久顺序节点、临时节点和临时顺序节点。Dubbo使用ZooKeeper作为注册中心时,只会创建持久节点和临时节点两种
- 持久节点:服务注册后保证节点不会丢失,注册中心重启也会存在
- 持久顺序节点:在持久节点特性的基础上增加了节点先后顺序的能力
- 临时节点:服务注册后连接丢失或session超时,注册的节点会自动被移除
- 临时顺序节点:在临时节点特性的基础上增加了节点先后顺序的能力
- 树形结构的关系:
- 树的根节点是注册中心分组,下面有多个服务接口,分组值来自用户配置dubbo:registry中的 group 属性,默认是/dubbo
- 服务接口下包含4类子目录,分别是providers、consumers、routers、configurators,这个路径是持久节点
- 服务提供者目录(/dubbo/service/providers) 包含的接口有多个服务者URL元数据信息
- 服务消费者目录(/dubbo/service/consumers) 包含的接口有多个消费者URL元数据信息
- 路由配置目录(/dubbo/service/routers)下面包含多个用于消费者路由策略元数据信息
- 动态配置目录(/dubbo/service/configurators)下面包含多个用于服务者动态配置URL元数据信息
3.2 订阅/发布
- 树形结构的注册中心,每个节点类型分为持久节点、持久顺序节点、临时节点和临时顺序节点。Dubbo使用ZooKeeper作为注册中心时,只会创建持久节点和临时节点两种
- ZooKeeper 的实现
- 发布的实现
- 服务提供者和消费者都需要把自己注册到注册中心。服务提供者的注册是为了让消费者感知服务的存在,从而发起远程调用;也让服务治理中心感知有新的服务提供者上线
- 订阅的实现
- 订阅通常有pull和push两种方式,一种是客户端定时轮询注册中心拉取配置,另一种是注册中心主动推送数据给客户端。目前Dubbo采用的是第一次启动拉取方式,后续接收事件重新拉取数据
3.3 缓存机制
- 订阅通常有pull和push两种方式,一种是客户端定时轮询注册中心拉取配置,另一种是注册中心主动推送数据给客户端。目前Dubbo采用的是第一次启动拉取方式,后续接收事件重新拉取数据
- 发布的实现
- 消费者或服务治理中心获取注册信息后会做本地缓存。内存中会有一份,保存在Properties对象里,磁盘上也会持久化一份文件,通过file对象引用
- 缓存的加载
- 在服务初始化的时候,AbstractRegistry构造函数里会从本地磁盘文件中把持久化的注册数据读到Properties对象里,并加载到内存缓存中
- 缓存的保存与更新
- 缓存的保存有同步和异步两种方式。异步会使用线程池异步保存,如果线程在执行过程中出现异常,则会再次调用线程池不断重试
3.4 重试机制
- 缓存的保存有同步和异步两种方式。异步会使用线程池异步保存,如果线程在执行过程中出现异常,则会再次调用线程池不断重试
- FailbackRegistry 继承了AbstractRegistry,并在此基础上增加了失败重试机制作为抽象能力
- FailbackRegistry抽象类中定义了一个ScheduledExecutorService,每经过固定间隔(默认为5秒)调用FailbackRegistry#retry()方法
3.5 设计模式 - 模板模式
-
整个注册中心的逻辑部分使用了模板模式
-
- AbstractRegistry实现了 Registry接口中的注册、订阅、查询、通知等方法,还实现了磁盘文件持久化注册信息这一通用方法。但是注册、订阅、查询、通知等方法只是简单地把URL加入对应的集合,没有具体的注册或订阅逻辑
-
FailbackRegistry又继承了 AbstractRegistry,重写了父类的注册、订阅、查询和通知等方法,并且添加了重试机制。此外,还添加了四个未实现的抽象模板方法
-
- 工厂模式
-
所有的注册中心实现,都是通过对应的工厂创建
-
AbstractRegistryFactory 实现了 RegistryFactory 接口的 getRegistry(URL url)方法,是一个通用实现,主要完成了加锁,以及调用抽象模板方法createRegistry(URL url)创建具体实现等操作,并缓存在内存中
-
每种注册中心都有自己具体的工厂类,在RegistryFactory接口中判断
-