饿了么全站成功升级 Dubbo3

升级目标

elem-arc

这里是饿了么的的基本部署架构图。

在升级之前,饿了么的微服务框架采用的是 HSF2,跨单元的 RPC 调用是通过 proxy 中转代理,在这个过程中 proxy 所承载的机器数和流量迅速增长,比较突出的一点是 proxy 在订阅所有的地址数据后资源消耗和稳定性都收到严峻挑战。

通过全站升级 Dubbo3,业务线期望达到两个目标:

  • 将地址模型切换到应用级服务发现大幅减轻中心化节点和消费端节点的资源消耗压力。
  • 以应用级服务发现架构下的全局共享注册中心取代 proxy 模式,实现跨单元节点通信直连。

升级过程

eleme-upgrade1

不论是针对 Dubbo2 还是 HSF2,我们都做了全面的 API 兼容,因此 Dubbo3 基本可以做到零改造升级,并且每个应用都是独立透明升级,不需要关心它的上下游应用的升级状态,因为 Dubbo3 升级之后不论是从地址发现模型还是协议的默认行为都保持与 2.0 版本兼容,用户可以在任意时间点对任意应用按需切换 Dubbo3 行为。 如右图所示,我们模拟展示了饿了么集群 Dubbo3 升级过程的一个中间状态,其中灰色标记的是老版本 HSF2 应用,橙色和绿色标记的是已经升级 Dubbo3 的应用,橙色部分的应用及其调用链路代表不但已经升级到 Dubbo3,同时也完成了 Dubbo3 行为的切换,在这里是指已经切换到了应用级地址模型。这里的升级过程主要为了说明 Dubbo3 框架升级的兼容性和独立性。

接下来,我们详细分析一下橙色部分节点往 Dubbo3 应用级发现迁移的具体过程。

elem-upgrade-provider

首先看 Provider 侧,服务提供者在升级 Dubbo3 后会默认保持双注册行为,即同时注册接口级地址和应用级地址到注册中心,一方面保持兼容,另一方面为未来消费端迁移做好准备。双注册的开关可通过 -Ddubbo.application.register-mode=al/interface/interface控制,我们推荐保持双注册的默认行为以减少后续迁移成本。

大家可能担心双注册给注册中心带来的存储压力,实际上在应用级服务发现模型下这并不是一个问题,因为大家如果回想前面我们对应用级服务发现工作原理的分析,注册地址已经被大幅精简,根据我们实际推算,每多注册一条应用级服务发现 URL 地址,只会增加 0.1% ~ 1% 的额外开销。

elem-upgrade-consumer

与提供端类似,要实现平滑迁移消费端也要经历双订阅的过程,流程上就不再赘述。消费端的双订阅行为也可通过规则或开关进行动态调整,控制消费端的消费的某个服务、应用迁移到应用级地址模型;除此之外,Dubbo3 还内置了自动决策机制,在发现应用级地址可用的情况下即会自动完成切换,并且这个行为是默认的。

以下是消费端双订阅时的选址流程:

elem-upgrade-consumer1

升级效果

elem-result

饿了么成功升级 Dubbo3 及应用级服务发现模型,实现了去 proxy 架构的目标,在我们关心的服务发现数据链路上:

  • 数据注册与订阅的传输量下降 90%
  • 注册中心数据存储的总体资源占用下降 90%
  • 消费端服务框架自身的常驻内存消耗下降达 50% 集群总体的稳定性、性能都得到明显提升,也为未来容量扩展做好准备。

最后修改 June 9, 2022: update docs (#1100) (ee727525aa)