摘要
本博文将介绍Dubbo最新的服务治理平台的实现原理。详细介绍服务治理中的路由规则、动态
配置、访问控制、权重管理、负载均衡的实现原理。
服务治理平台总体结构
Dubbo有新旧两个服务治理平台,旧的服务治理平台在Dubbo 2.6.0以后就从源码中被移除了,现在已经没有继续维护。新的服务治理平台并没有包含在Dubbo源码中,而是独立的一个仓库,有兴趣的读者可以在GitHub上搜索dubbo-ops来了解详细信息。新的服务治理平台分为前端Web部分和后台部分,并做了前后端分离,前端可以独立启动部署。前端技术使用Vue +Vuetify的组合方式,后台则直接使用了 SpringBooto整个服务治理平台还在开发中,很多特性还未上线,因此本章会优先基于新的服务治理平台讲解,对于新服务治理平台还未实现的功能,将基于旧的服务治理平台讲解。
服务治理平台包含服务治理的功能,和一般的MVC项目一样,前端通过REST接口请求后端服务,后端Controller收到对应请求后调用Service处理具体逻辑。
API接口功能
Controller | 作用 |
ServiceController | 负责接收服务搜索的请求,包括服务列表的查询和单个服务详情的查询 |
RoutesController | 负责接收路由规则的请求,包括规则的新增、删除、修改、更新,单条规则详 情的查询 |
OverridesController | 负责接收动态配置的请求,包括配置的新增、删除、修改、更新、禁用、启用, 单条配置详情的查询 |
AccessesController | 负责接收访问控制的请求,包括访问规则的新增、删除、修改、更新,单条规 则详情的查询 |
Weightcontroller | 负责权重管理的请求,包括权重配置的新增、删除、修改、更新,单条权重详 情的查询 |
LoadBalanceController | 负责负载均衡规则的请求,包括负载均衡配置的新增、删除、修改、更新,单 条权重详情的查询 |
服务治理平台的实现原理
服务搜索
服务搜索是通过不同的过滤条件,在本地的注册数据缓存里,查找出合适的结果集。因此,我们首先看一下抽象父类是如何获取到注册中心的数据并缓存到本地的。主要是通过一个工具类RegistryServerSync实现的,它继承了两个Spring接口和一个Dubbo注册中心接口。
熟悉Spring的读者会知道,继承了 Spring的InitializingBean接口后需要实现afterPropertiesSet()方法,Spring 在所有 Bean 的属性被设置后,调用 RegistryServerSync 实现的 afterPropertiesSet 方法。继承 DisposableBean 接口则需要实现 destroy()方法,Spring容器在释放Bean的时候会调用该方法。
除此之外,RegistryServerSync还继承了 NotifyListener接口,这个是Dubbo注册中心的监听接口,说明RegistryServerSync在监听到注册中心的变化时,会调用自己实现的notify(List<URL> urls)方法更新本地的缓存数据。
- 在Bean初始化时,在afterPropertiesSet()方法中会订阅注册中心。直接调用注册中心模块的registryService#subscribe订阅,把this传入并作为监听者,因为RegistryServerSync也实现了监听接口。
- 监听到变化时候,通过notify(List<URL> urls)方法更新本地的缓存数据。对于empty协议的变更,如果服务配置的group和version (Dubbo支持一个接口多个版本)的值是*,则清空所有本地的这个节点;如果指定了特定的group和version,则只删除指定的节点。对于非empty协议的变更,则把数据按照类目、ServiceKey两种维度分别保存一份,更新本地缓存。ServiceKey的规则是:group + 7' + 接口名 + + versiono
- Bean被Spring容器销毁时,在destroy()方法中会取消订阅注册中心,直接调用registryService#unsubscribe 取消订阅。
获取注册中心的数据,并缓存到本地后,providerServicelmpl或ConsumepServicelmpl
的查找就很好实现了,通过查询的参数遍历缓存,过滤出合适的结果即可。现有新版搜索支持
根据Service名称、IP地址、服务名称进行搜索;旧版还支持创建、禁用、启用服务,这些特
性是通过override特性实现的。
路由规则
route规则可以为不同的服务指定特定的路由规则,route协议在注册中心的URL以route://开头。前端可以配置的参数如表12-3所示。
路由规则示例
最后的conditions的意思就是,调用com.test.xxService服务中所有以find、list、get> is开头的方法,都路由到172.22.3.94、172.22.3.95、172.22.3.96这三个地址中的一个。它们之间使用=>表示路由。最终,整个route对象会转换为以route://开头的URL。增删改查的实现逻辑与override相同,都使用“注册”、"取消注册”方法来实现。
动态配置
override特性主要使用在动态参数的更新上,各个节点监听到注册中心的参数发生变化,从而更新本地的参数信息。override类型的URL是以override://开头的,允许整个URL中只有部分属性变化,监听者监听到变化后会做部分更新。override包含以下属性的配置,
override具体操作逻辑:
- 新增。把 override 对象转换成 URL,通过 registryservice.register(url)把 URL
- 注册到注册中心。
- 修改。根据Hash值找到老的URL,如果没找到则说明数据己经被修改,抛出异常;如果找到了,则先取消注册老的URL,再注册新的URLO
- 删除。先根据id获取老的URL,再直接取消注册老的URL。
- 启用/禁用。首先根据id获取老的URL,在新URL的params属性里把enabled设置为true或false,然后取消注册老的URL,最后注册新的URL。
权重管理
框架中不同的负载均衡策略还会受到权重的影响。当用户对服务设置了权重后,对权重高的节点会提高调用频率,对权重低的节点会降低调用频率。Weight的实现与其他配置功能的实现相似,首先把前端传入的参数转换为Weight对象,然后把Weight对象转换为URL,最后使用overrideService把URL发布到注册中心
负载均衡
如果用户不做任何配置,则默认使用RandomLoadBalance,即加权随机负载算法。用户可以在服务治理平台里修改某个服务的负载均衡策略,其配置参数较少。负载均衡对象会被转换成一个override对象,并使用override协议实现新增、更新、删除等操作。
博文参考
Dubbo-Principle: 本项目主要是介绍的Dubbo等相关原理,同时实现简单的RPC版本
GitHub - apache/dubbo-admin: The ops and reference implementation for Apache Dubbo
深入理解Apache Dubbo与实战.pdf