概述
Dubbo微服务体系中, 注册中心是其核心组件之一。 Dubbo通过注册中心实现了分布式
环境中各服务之间的注册与发现, 是各个分布式节点之间的纽带。 其主要作用如下:
1、动态加入。 一个服务提供者通过注册中心可以动态地把自己暴露给其他消费者, 无须
消费者逐个去更新配置文件
2、动态发现。 一个消费者可以动态地感知新的配置、 路由规则和新的服务提供者, 无须
重启服务使之生效。
3、动态调整。 注册中心支持参数的动态调整, 新参数自动更新到所有相关服务节点。
4、统一配置。 避免了本地配置导致每个服务的配置不一致问题。
Dubbo的注册中心源码在模块dubbo-registry中, 里面包含了五个子模块, 如下图所示
从_dubbo-registry_的模块中可以看到, Dubbo主要包含四种注册中心的实现, 分别是ZooKeeper、 Redis 、 Simple、 Multicast。
其中ZooKeeper是官方推荐的注册中心, 在生产环境中有过实际使用, 具体的实现在Dubbo源码的dubbo-registry-zookeeper模块中。
Dubbo拥有良好的扩展性, 如果以上注册中心都不能满足需求, 那么用户可以基于RegistryFactory和Registry自行扩展。 后面章节会专门介绍注册中心的扩展
工作流程
注册中心的总体流程比较简单, Dubbo官方也有比较详细的说明, 总体流程如图3-1所示。
服务提供者启动时, 会向注册中心写入自己的元数据信息, 同时会订阅配置元数据信息。
消费者启动时, 也会向注册中心写入自己的元数据信息, 并订阅服务提供者、 路由和
配置元数据信息。
服务治理中心(dubbo-admin)启动时, 会同时订阅所有消费者、 服务提供者、 路由和
配置元数据信息。
当有服务提供者离开或有新的服务提供者加入时, 注册中心服务提供者目录会发生变
化, 变化信息会动态通知给消费者、 服务治理中心。
当消费方发起服务调用时,会异步将调用、 统计信息等上报给监控中心(dubbo-monitorsimple)
数据结构
注册中心的总体流程相同, 但是不同的注册中心有不同的实现方式,其数据结构也不相同。
ZooKeeper. Redis等注册中心都实现了这个流程。 由于有些注册中心并不常用, 因此本章只分
析ZooKeeper和Redis两种实现的数据结构。
ZooKeeper 原理概述
ZooKeeper是树形结构的注册中心, 每个节点的类型分为持久节点、 持久顺序节点、 临时
节点和临时顺序节点。
持久节点: 服务注册后保证节点不会丢失, 注册中心重启也会存在。
持久顺序节点: 在持久节点特性的基础上增加了节点先后顺序的能力。
临时节点: 服务注册后连接丢失或session超时, 注册的节点会自动被移除。
临时顺序节点: 在临时节点特性的基础上增加了节点先后顺序的能力。
Dubbo使用ZooKeeper作为注册中心时, 只会创建持久节点和临时节点两种, 对创建的顺
序并没有要求。
/dubbo/com.foo.BarService/providers是服务提供者在ZooKeeper注册中心的路径示例,
是一种树形结构, 该结构分为四层: root (根节点, 对应示例中的dubbo)、 service (接口名称,
对应示例中的com.foo.BarService)>四种服务目录(对应示例中的providers,其他目录还有
consumers、 routers、 configurators)。 在服务分类节点下是具体的Dubbo服务URL。 树形结
构示例如下:
+ /dubbo
±- service
±- providers
±- consumers
±- routers
±- configurators
树形结构的关系:
(1) 树的根节点是注册中心分组, 下面有多个服务接口, 分组值来自用户配置
dubbo:registry中的 group 属性, 默认是/dubbo。
(2) 服务接口下包含4类子目录, 分别是providers>
这个路径是持久节点。
consumers> routers> configurators,
(3) 服务提供者目录(/dubbo/service/providers)
元数据信息。
(4) 服务消费者目录(/dubbo/service/consumers)
元数据信息。
(5) 路由配置目录(/dubbo/service/routers)下面包含多个用于消费者路由策略
元数据信息。 路由配置会在第7章详细介绍。
(6) 动态配置目录(/dubbo/service/configurators)下面包含多个用于服务者动态配置
URL元数据信息。 动态配置也会在第7章详细介绍。
下面通过树形结构做一个简单的演示, 如下图所示。
在Dubbo框架启动时, 会根据用户配置的服务, 在注册中心中创建4个目录, 在providers
和consumers目录中分别存储服务提供方、 消费方元数据信息, 主要包括IP、 端口、 权重和应
用名等数据。
在Dubbo框架进行服务调用时, 用户可以通过服务治理平台(dubbo-admin)下发路由配
置。 如果要在运行时改变服务参数, 则用户可以通过服务治理平台(dubbo-admin)下发动态配
置。 服务器端会通过订阅机制收到属性变更, 并重新更新已经暴露的服务。
在深入讲解Dubbo内部原理之前, 可以先参考表3-2中目录包含的信息。
服务元数据中的所有参数都是以键值对形式存储的。 以服务元数据为例:
dubbo://192.168.0.1.20880/com.alibaba.demo.Servicecategory=provider&name=demo-prov
ider&…服务元数据中包含2个键值对, 第1个key为category, key关联的值为provider。
在Dubbo中启用注册中心可以参考如下方式:
<dubbo:registry protocol=“zookeeper” address=“ip:port,ip:port” />
<dubbo:registry protocol=“zookeeper” address=“ip:port|ip:port” />
Redis原理概述
Redis注册中心也沿用了 Dubbo抽象的Root、 Service> Type> URL四层结构。 但是由于Redis
属于NoSQL数据库, 数据都是以键值对的形式保存的, 并不能像ZooKeeper-样直接实现树形
目录结构。 因此, Redis使用了 key/Map结构实现了这个需求, Root、 Service、 Type组合成Redis
的keyo Redis的value是一个Map结构, URL作为Map的key,超时时间作为Map的value,
如下图所示。