共计 7585 个字符,预计需要花费 19 分钟才能阅读完成。
作者:李斌、邱炜
背景
咱们公司从 2015 年开始就使⽤ Dubbo 作为微服务框架,当社区推出 Dubbo 3 时,咱们也⽴刻跟进并做了深⼊调研,发现 Dubbo 3 的应⽤ / 实例级服务注册和发现模式可能在肯定水平上解决咱们以后注册中⼼⾯临的压⼒,解决稳定性和安全性问题。同时 Dubbo 3 在服务治理上也做了降级,符合云原⽣架构,⽽且 Dubbo 3 可能向下兼容 Dubbo 2,这也将升高降级的老本和⻛险。
降级我的项目有了阶段性的停顿,目前依然在进行中。通过本⽂,咱们对公司外部的 Dubbo 3 降级过程及收益等做了深⼊总结。
社区对于 Dubbo 3 的外围性能介绍
Dubbo 社区对于 Dubbo 3 的文档和材料越来越欠缺,以下是咱们从社区援用的一些内容。
下一代云原生服务框架
Dubbo 3 被社区寄予厚望,将其视为下一代云原生服务框架打造,Dubbo 3 提供的外围个性列表,次要包含四局部。
- 全新服务发现模型 。利用粒度服务发现,面向云原生设计,适配基础设施与异构零碎;性能与集群伸缩性大幅晋升。
- 下一代 RPC 协定 Triple。基于 HTTP/2 的 Triple 协定,兼容 gRPC;网关穿透性强、多语言敌对、反对 Reactive Stream。
- 对立流量治理模型 。面向云原生流量治理,SDK、Mesh、VM、Container 等对立治理规定;可能反对更丰盛的流量治理场景。
- Service Mesh。在最新的 3.1.0 的版本中反对 Sidecar Mesh 与 Proxyless Mesh,提供更多架构抉择,升高迁徙、落地老本。
首先是性能、资源利用率的晋升。社区材料显示,降级 Dubbo 3 的利用预期能实现单机内存 50% 的降落,对于越大规模的集群成果将越显著,Dubbo 3 从架构上反对百万实例级别的集群横向扩大,同时依赖利用级服务发现、Triple 协定等能够大大提供利用的服务治理效率和吞吐量。
其次,Dubbo 3 让业务架构降级变得更容易、更正当,尤其是 RPC 协定,在 2.x 版本中,web、挪动端与后端的通信都要通过网关代理,实现协定转换、类型映射等工作,Dubbo 3 的 Triple 协定让这些变得更容易与天然;并通过流式通信模型满足更多的应用场景。
最初,得益于 Dubbo 3 的欠缺云原生解决方案,Dubbo 3 的 Mesh 架构能够帮忙业务屏蔽底层云原生基础设施细节,让业务更专一于业务,这也是 Mesh 的最基本的劣势。
利用级服务发现外围原理
咱们从 Dubbo 最经典的工作原理图说起,Dubbo 从设计之初就内置了服务地址发现的能力,Provider 注册地址到注册核心,Consumer 通过订阅实时获取注册核心的地址更新,在收到地址列表后,Consumer 基于特定的负载平衡策略发动对 Provider 的 RPC 调用。
在这个过程中:
- 每个 Provider 通过特定的 key 向注册核心注册本机可拜访地址;
- 注册核心通过这个 key 对 Provider 实例地址进行聚合;
- Consumer 通过同样的 key 从注册核心订阅,以便及时收到聚合后的地址列表;
再来看一下 Provider 向注册核心注册的 URL 地址的具体格局,这里把 URL 地址数据划分成了几份:
- 首先是实例可拜访地址,次要信息蕴含 ip port,是生产端将基于这条数据生成 tcp 网络链接,作为后续 RPC 数据的传输载体。
- 其次是 RPC 元数据,元数据用于定义和形容一次 RPC 申请,表明这条地址数据是与某条具体的 RPC 服务无关的,它的版本号、分组以及办法相干信息。
- 下一部分是 RPC 配置数据,局部配置用于管制 RPC 调用的行为,还有一部分配置用于同步 Provider 过程实例的状态,典型的如超时工夫、数据编码的序列化形式等。
- 最初一部分是自定义的元数据,这部分内容区别于以上框架预约义的各项配置,给了用户更大的灵活性,用户可任意扩大并增加自定义元数据,以进一步丰盛实例状态。
联合以上对于 Dubbo 2 接口级地址模型的剖析,以及最开始的 Dubbo 基本原理图,能够得出这么几条论断:
- 地址发现聚合的 key 就是 RPC 粒度的服务。
- 注册核心同步的数据不止蕴含地址,还蕴含了各种元数据以及配置。
- 得益于 1 与 2,Dubbo 实现了反对利用、RPC 服务、办法粒度的服务治理能力。
这就是始终以来 Dubbo 2 在易用性、服务治理功能性、可扩展性上强于很多服务框架的真正起因。
面对这样的地址数量级放大的问题,在 Dubbo 3 架构下,社区认真思考了两个问题:
- 如何在保留易用性、功能性的同时,从新组织 URL 地址数据,防止冗余数据的呈现,让 Dubbo 3 能撑持更大规模集群程度扩容?
- 如何在地址发现层面与其余的微服务体系如 Kubernetes、Spring Cloud 买通?
最终,社区给出的计划也是十分奇妙和经典。Dubbo 3 的利用级服务发现方案设计的基本思路是:地址发现链路上的聚合元素也就是之前提到的 Key 由服务调整为利用,这也是其名称叫做利用级服务发现的由来, 与 Kubernetes 和 Spring Cloud 的服务注册发现处于同一粒度,可能平滑买通;另外,通过注册核心同步的数据内容上做了大幅精简,只保留最外围的 ip、port 地址数据。通过上述调整,利用级别服务发现在放弃接口级地址模型易用性的同时,实现了地址单条数据大小和总数量的降落。
元数据、配置数据以及自定义数据等通过元数据中心或者 MetadataService 进行同步,且将所有的数据生成一个 Metadata Revision,如果 Metadata Revision 雷同则认为元数据等信息雷同,通过这种形式来升高元数据中心或 MetadataService 的拜访频次。
后期调研
理解了 Dubbo 3 的外围性能以及利用级服务发现的工作原理后,咱们开始进入前期工作阶段。
性能压测
从社区的材料来看,Dubbo 3 各方面都十分不错,然而咱们还得本人测验一次,所以咱们应用以后在用的 Dubbo 2 外部定制版和 Dubbo 3 的性能压测,压测的次要场景在于同步调用,异步场景只做了 Dubbo 3 的压测, 以下压测数据和论断仅供参考 。
结果表明 Dubbo 3 在性能下面的确做了很多的优化,在雷同 CPU 使用率的状况下,Dubbo 3 的 TPS 是要高于 Dubbo 2 的;TPS 相当的状况下,Dubbo 3 的 CPU 使用率要低于 Dubbo 2。尤其是 Dubbo 2 的接口级与 Dubbo 3 的实例级,在 TPS 相当的状况下,Dubbo 3 的 CPU 使用率要较定制版的 Dubbo 2 低 20% 左右。
压测环境:
类别 | 版本 | 机器配置 |
---|---|---|
Provider | Dubbo 3.0.4 | 4C8G |
Consumer | Dubbo 3.0.4 | 4C8G |
Provider | Dubbo 2.5.3.22(基于 2.5.3 版本定制) | 4C8G |
Consumer | Dubbo 2.5.3.22(基于 2.5.3 版本定制) | 4C8G |
测试场景:
应用的是 Dubbo 协定,接口没有其它逻辑,间接将输出返回给消费者,接口数据包大小 500B,每个场景压 30 分钟。
测试数据 (仅供参考):
降级前调研
做了压测失去 Dubbo 2 和 Dubbo 3 的压测数据后,咱们开始打算将 Dubbo 3 引入公司进行试点,此时,咱们须要思考 Dubbo 3 与 Dubbo 2 的兼容和迁徙重构问题,降级指标,以及 Dubbo 3 提供有哪些能力反对降级和迁徙。
- 降级的兼容和迁徙重构问题
思考到公司的零碎规模,要将 Dubbo 2 降级到 Dubbo 3 却不是一个简略的过程,尤其是公司的 Dubbo 2 版本在原开源版本根底之上做了不少优化和扩大,涵盖了 OPS 服务治理、Monitor 数据指标监控、服务注册和发现、RPC 灰度路由、链路剖析、序列化编解码、作为其余根底框架的底层反对等多个方面。同时 Dubbo 3 社区也处于沉闷的状态,咱们也心愿可能继续享受 Dubbo 社区的技术红利,在这样的背景下不得不思考三个问题:
- 须要解决公司版本的 Dubbo 2 与 Dubbo 3 的兼容问题
- 原有性能的迁徙重构问题
- 不在 Dubbo 3 的源码上做改变,放弃和社区版本统一
得益于 Dubbo 良好的扩大能力,咱们能够通过 Dubbo 的 SPI 和 IoC 模块在 Dubbo 3 的根底之上优雅的兼容公司版本的 Dubbo 2,不必改变 Dubbo 3 源码,只有研发 Dubbo 3 扩大包追随 Dubbo 3 版本的 API 降级即可,这个降级改变的老本和从社区获取红利相比是比拟小的。
- 降级指标
既然历史包袱的解决方案曾经有了,那么就要思考降级的指标了。首先确定的是,最终咱们将会采纳实例级的服务注册和服务发现,其次咱们目前应用的注册核心是 Zookeeper,而 Dubbo 社区更举荐应用的注册核心是 Nacos,而且咱们在验证阶段时也裸露过几个在 Zookeeper 上呈现而在 Nacos 上没有呈现的问题,这也使得咱们开始思考未来是否将注册核心最终也迁徙到 Nacos 上。
同时,咱们也心愿整个迁徙过程是平滑、可控的,咱们整体计划也要将危险把控作为外围要点思考,尽可能的做到失败降级、实时可控。
综上,咱们将降级的指标演绎为上面几点:
- 平滑的从 Dubbo 2 降级到 Dubbo 3
- 将接口级服务注册和发现模式平滑的迁徙到利用级服务注册和发现模式为
- 前面平滑迁徙注册核心做好筹备
- 迁徙过程可监控、可观测。
- 迁徙过程要可灰度、可实时管控
- 对立 Dubbo 3 的通用配置标准,尽量适配原 Dubbo 2 的 Export 和 Refer 形式。
- Dubbo 3 对于迁徙的撑持能力
后面介绍的是咱们的指标,然而如何把 Dubbo 3 的原生设计理念融入到现实情况中呢?以下是咱们的相干思考,并在验证过程中。
首先 Dubbo 3 可能反对在 RegistryUrl 上通过参数治理 Provider 和 Consumer 以不同的模式进行服务注册和服务发现,其中外围参数名有: registry-type, registry-protocol-type, register-mode。
其次,Dubbo 3 能够反对应用多个注册核心,不同的注册核心通过下面的 RegistryUrl 参数管制注册核心的服务注册模式和服务发现模式。而且还能够通过 ProviderConfig 和 ConsumerConfig 这两个这两个 Config 类别离治理 Provider 侧和 Consumer 侧应用的注册核心。在 Consumer 侧,如果有应用多个注册核心,默认会应用 ZoneAwareCluster 创立的 ZoneAwareClusterInvoker 来进行负载平衡,从类名上能够看出,该 ClusterInvoker 是有提供区域感知的能力,查看源码时发现它还提供了 preferred 的性能,只在相应的 registryUrl 中增加了 preferred=true,这个 registryUrl 创立的 ClusterInvoker 就会被优先调用。
在同一注册核心进行接口级迁徙到实例级的场景中,Dubbo 3 的 MigrationInvoker 也提供了相应的反对,MigrationInvoker 能够依据 MigrationRule 来管制实例级的 RPC 流量,并且依据 MigrationRuleListener 可能实时监听到指定利用的 MigrationRule 的变更。
对于 RPC 的监控在 Dubbo 中始终由 MonitorFilter 和 DubboMonitor 提供 RPC 监控数据的收集和上报,收集的数据有消费者的 ip 端口、提供者的 ip 端口、利用名称、DubboService、Method、以及胜利数、失败数、输出字节数、输入字节数、耗时、并发数等。
这些能力可能满足根本的迁徙工作,联合咱们的现状来看,绝对降级指标要求的平滑迁徙,迁徙流量可观测、可灰度、可管控还有一些间隔,不过在梳理 Dubbo 3 这块能力的时候,也找到了绝对简略的扩大计划。到此,对于整体的迁徙计划也有了一个大抵的雏形。
降级 & 迁徙方案设计
计划的设计重点放在“平滑、可控”两点,依据 Dubbo 3 的新架构,目前正在验证中的迁徙计划示意图如下:
从上图能够看出,在整个降级迁徙的过程中,利用域中会存在多个 Dubbo 版本,Dubbo 3 是可能兼容社区的 Dubbo 2 版本,而咱们公司外部的 Dubbo 2 版本是基于 Dubbo 2.5.3 开源版本深度定制过的,在 OPS 服务治理、Monitor 数据指标监控、服务注册和发现、RPC 灰度路由、序列化编解码等方面都做了扩大定制,咱们的思路是由 Dubbo 3 基于 Dubbo 的 SPI 采纳扩大的形式或者 ExtensionLoader 的 Wrapper 模式去兼容定制版的 Dubbo2。
除了利用外,在 Dubbo 3 的架构根底上划分了 3 个逻辑域,别离是注册域、配置管控域和监控域。
注册域次要服务于服务的注册和发现,例如 Provider 在 DubboService 裸露时,将服务信息和元数据信息上报到注册域的注册核心和元数据中心,Consumer 通过注册核心和元数据中心来发现服务。配置管控域次要是治理利用配置和迁徙流量管控,Dubbo 3 提供的配置核心反对本身能力的配置,所以流量规定的配置由 Dubbo 3 的配置核心进行保护,Dubbo 3 的 DynamicConfigration 提供了很多对于动静配置的办法能够间接应用。监控域除了原 RPC 流量的监控外,还细分了迁徙流量的监控,在迁徙过程中,能够通过监控直观的看到迁徙流量的现状,呈现问题时,也能够及时报警告诉相干人员染指。
整个降级过程分为 3 个阶段:
- 第一阶段:将 Dubbo 2 降级到 Dubbo 3 的接口级,验证性能、兼容性、性能和稳定性
- 第二阶段:接口级和利用级双注册,通过 MigrationRule 和 RegistryMigrationRule 治理 RPC 流量
- 第三阶段:全面切换到利用级,撤掉 MigrationRule 和 RegistryMigrationRule
Dubbo 3 扩大兼容 Dubbo 2 定制版本
思考到 Dubbo 3 社区版本的迭代状况,最终决定 Dubbo 3 兼容 Dubbo 2 定制版本的插件以 SDK 的形式独自保护,实现兼容的扩大性能次要有如下内容:
- RPC 正向透递与反向透传
在 Consumer 侧和 Provider 侧扩大 Filter 接口实现类,为正向与反向透传数据实现其发送和接管的性能。Dubbo 2 定制版是在序列化编解码层面对 RpcResult 进行了批改,要兼容这一逻辑也只能在序列化编解码层面去反对,采纳 Wrapper 模式对 Codec2 这个 SPI 进行加强,与其它扩大类一并实现该兼容性能。
- RPC 灰度路由
扩大 Dubbo 的 Router、Cluster 和 ConfiguratorFactory 等 SPI,与外部的 eunomia 灰度管控平台集成实现 RPC 灰度路由,替换并兼容掉原 Dubbo 2 定制版在其源码层面批改实现的灰度路由性能。
- Monitor 数据指标监控
扩大 Protocol、MonitorFilter、Monitor 等 SPI,与外部的监控核心实现对接,与 Dubbo 2 定制版的监控逻辑保持一致。
- OPS 反对实例级
在 OPS 层面,除了要兼容原接口级的服务管控外,还要增加实例级的服务管控。
- 其它中间件兼容
除了 Dubbo 自身的兼容外,外部还有局部自研的中间件也是有依赖 Dubbo 或者跟 Dubbo 有关联的,还要对这些中间件进行革新降级。
迁徙扩大
在 Dubbo 3 原有能力根底上,也要另外进行扩大以提供平滑迁徙的能力,咱们构想的设计方案如下:
- 扩大反对注册核心的迁徙可灰度、可管控
在 Dubbo 3 中,当 Consumer 侧利用了多个注册核心时,默认会通过 ZoneAwareCluster 创立 ZoneAwareClusterInvoker 来进行负载平衡,参考其实现能够扩大一个 Cluster 实现类和一个 ClusterInvoker 实现类将 ZoneAwareCluster 替换掉,注册核心迁徙的流量治理、灰度、降级等能力都在扩大的 ClusterInvoker 中去实现。
- 扩大反对接口级到实例级迁徙规定的全局配置管理
MigrationRule 由 MigrationRuleListener 通过 DynamicConfiguration 监听指定的利用的迁徙规定,如果一个零碎领有成千盈百个微服务利用时,由这种形式去治理,保护老本将会变高,咱们借鉴这个办法实现了全局级别的 MigrationRule 治理能力。
- 扩大迁徙流量可观测、可报警
Dubbo RPC 的流量监控曾经有 MonitorFilter 和 DubboMonitor 实现了,只是 MonitorFilter 不能辨认本次 RPC 申请的 Invoker 对象是通过哪个注册核心进行服务发现的,以及该 Invoke 对象的服务发现模式是接口级还是实例级的;咱们在 Consumer 侧新增一个 ClusterFilter 接口和 Filter 接口去实现这个辨认逻辑。
- 迁徙组件开关
在扩大的最初,要思考迁徙组件下线的问题,即便要下线也不可能再次调整业务工程将迁徙组件全副从依赖中删除掉,所以须要通过开关管制迁徙组件的性能下线。
配置对立治理
在降级和迁徙过程中,咱们可能会随时调整注册核心和迁徙规定的配置参数,为缩小出错的危险以及业务工程降级改变的工作量,这些公共的配置须要对立治理保护起来,Dubbo 3 的配置核心失常可能把这个工作较好的承接下来。
最终咱们又扩大了一个配置加载的组件,通过咱们公司外部的配置核心治理保护迁徙组件的开关和配置核心的连贯地址与超时等配置参数。有了这个组件后,新的利用能够不必放心 Dubbo 3 和迁徙的公共配置,老的利用也缩小了这部分公共配置的调整工作量。
危险预案
Dubbo 作为一个提供底层撑持能力的微服务框架,咱们始终把稳定性的要求放在首位,降级过程中任何一点意外,都可能导致线上问题,所以咱们整个计划都是在面向失败、面向危险设计的。除了在扩大的迁徙组件中实现了被动降级外,也着重思考了一些极其状况,同时为这些极其状况提供危险预案。线上环境可能会呈现各种意想不到的状况,在迁徙过程中须要事后思考各种危险,筹备欠缺的应答解决预案,保证系统疾速复原。
小结
Dubbo 2 是一个优良的微服务框架,提供的 SPI 以及 Extension 机制可能十分不便的让用户去扩大实现想要性能。Dubbo 3 在其根底之上,丰盛了不少新的 SPI,咱们花了很长的工夫去设计迁徙计划,真正花在迁徙组件上的开发工夫较短。
Dubbo 3 整体架构降级调整对于过来的服务注册压力也失去了解决。性能上也做了优化,架构降级后的 Dubbo 3 也更适应目前云原生的架构,Dubbo 3.1.x 版本反对 Sidecar 和 Proxyless 的 Mesh 计划,而且社区也在筹备开源 Java Agent 形式的 Proxyless,这样就能较好的将微服务架框的 Framework 与数据面解耦,升高微服务框架的保护老本和降级老本。
社区合作
目前该我的项目依然在继续降级中,咱们跟社区放弃着严密的分割,期间碰到不少问题,都失去了社区开发同学耐⼼解答并最终给予解决。
对于要降级 Dubbo3 的⽤户,能够在社区的 Github 置顶 Issue 进⾏注销。