From 7155fcb06ebb66b8c837eaa019f7ced98a959c72 Mon Sep 17 00:00:00 2001 From: Ken Liu Date: Sun, 23 Oct 2022 13:32:58 +0800 Subject: [PATCH] Add new use cases (#1567) --- content/zh/users/_index.md | 36 ++-- content/zh/users/dianxiaomi.md | 118 ++++++++++++ content/zh/users/fenghuodi.md | 7 - content/zh/users/guazi.md | 174 +++++++++++++++++ content/zh/users/pingan.md | 214 ++++++++++++++++++++- content/zh/users/zhonglunwangluo.md | 60 ++++++ static/imgs/v3/users/pingan-1.png | Bin 0 -> 72772 bytes static/imgs/v3/users/pingan-2.png | Bin 0 -> 171346 bytes static/imgs/v3/users/pingan-3.png | Bin 0 -> 98272 bytes static/imgs/v3/users/pingan-4.png | Bin 0 -> 114615 bytes static/imgs/v3/users/pingan-5.png | Bin 0 -> 112844 bytes static/imgs/v3/users/pingan-6.png | Bin 0 -> 112176 bytes static/imgs/v3/users/pingan-7.png | Bin 0 -> 71509 bytes static/imgs/v3/users/pingan-8.png | Bin 0 -> 62863 bytes static/imgs/v3/users/yunxiaomi-1.png | Bin 0 -> 633721 bytes static/imgs/v3/users/yunxiaomi-2.png | Bin 0 -> 302005 bytes static/imgs/v3/users/yunxiaomi-3.png | Bin 0 -> 129716 bytes static/imgs/v3/users/yunxiaomi-4.png | Bin 0 -> 94913 bytes static/imgs/v3/users/zhonglunwangluo-1.png | Bin 0 -> 286881 bytes static/imgs/v3/users/zhonglunwangluo-2.png | Bin 0 -> 76830 bytes static/imgs/v3/users/zhonglunwangluo-3.png | Bin 0 -> 71265 bytes static/imgs/v3/users/zhonglunwangluo-4.png | Bin 0 -> 118708 bytes 22 files changed, 586 insertions(+), 23 deletions(-) create mode 100644 content/zh/users/dianxiaomi.md delete mode 100644 content/zh/users/fenghuodi.md create mode 100644 content/zh/users/guazi.md create mode 100644 content/zh/users/zhonglunwangluo.md create mode 100644 static/imgs/v3/users/pingan-1.png create mode 100644 static/imgs/v3/users/pingan-2.png create mode 100644 static/imgs/v3/users/pingan-3.png create mode 100644 static/imgs/v3/users/pingan-4.png create mode 100644 static/imgs/v3/users/pingan-5.png create mode 100644 static/imgs/v3/users/pingan-6.png create mode 100644 static/imgs/v3/users/pingan-7.png create mode 100644 static/imgs/v3/users/pingan-8.png create mode 100644 static/imgs/v3/users/yunxiaomi-1.png create mode 100644 static/imgs/v3/users/yunxiaomi-2.png create mode 100644 static/imgs/v3/users/yunxiaomi-3.png create mode 100644 static/imgs/v3/users/yunxiaomi-4.png create mode 100644 static/imgs/v3/users/zhonglunwangluo-1.png create mode 100644 static/imgs/v3/users/zhonglunwangluo-2.png create mode 100644 static/imgs/v3/users/zhonglunwangluo-3.png create mode 100644 static/imgs/v3/users/zhonglunwangluo-4.png diff --git a/content/zh/users/_index.md b/content/zh/users/_index.md index 80e09b6f4ef4..3aee32b72137 100644 --- a/content/zh/users/_index.md +++ b/content/zh/users/_index.md @@ -25,20 +25,18 @@ Apache Dubbo 诞生于阿里巴巴微服务实践之中,在开源之后深受

{{< cardpane >}} - {{< card header="阿里云服务治理平台 MSE" >}} -阿里云基于 Dubbo 构建了微服务引擎产品 - MSE。MSE 支持 Zookeeper、Nacos 等官方扩展,同时在 Dubbo 上构建了丰富的服务治理能力。

-了解更多 - {{< /card >}} {{< card header="阿里巴巴的 Dubbo3 落地实践" >}} 阿里巴巴电商核心系统已成功升级到 Dubbo3 版本,用于取代上一代 HSF2 服务框架,2022 年起双 11 核心链路都将跑在 Dubbo3 之上。

了解更多 {{< /card >}} - + {{< card header="平安健康" >}} + 平安健康已完成全站 2.x 版本到 Dubbo3 的迁移,升级过程中与社区开发者进行了深度合作,中间也总结了一些升级经验,非常具有参考价值。

+ 了解更多 + {{< /card >}} {{< card header="工商银行 Dubbo3 应用级服务发现实践" >}} 工商银行为什么要选型 Dubbo3 应用级服务发现架构那?2.x 版本架构在超大规模集群实战上遇到了那些性能和容量瓶颈?

了解更多 {{< /card >}} - {{< /cardpane >}} {{< cardpane >}} @@ -46,13 +44,13 @@ Apache Dubbo 诞生于阿里巴巴微服务实践之中,在开源之后深受 饿了么当前有接近 2000 应用、10 万实例跑在 Dubbo3 之上,通过应用级服务发现与 Triple 协议解决了跨单元的互联互通问题。

了解更多 {{< /card >}} - {{< card header="平安健康" >}} - 平安健康目前正从 2.x 版本迁移到 Dubbo3,升级过程中与社区开发者进行了深度合作,中间也总结了一些升级经验,非常具有参考价值。

- 了解更多 - {{< /card >}} - {{< card header="烽火递" >}} - 烽火递的所有新业务都使用 Dubbo3 构建,由于没有 dubbo2 的迁移成本,业务得以很快的稳定上线,新业务都跑在 Dubbo3 的新特性之上。

- 了解更多 + {{< card header="阿里云服务治理平台 MSE" >}} + 阿里云基于 Dubbo 构建了微服务引擎产品 - MSE。MSE 支持 Zookeeper、Nacos 等官方扩展,同时在 Dubbo 上构建了丰富的服务治理能力。

+ 了解更多 + {{< /card >}} + {{< card header="中伦网络" >}} + 中伦网络在 2022 年完成了服务框架从 Dubbo2 到 Dubbo3 的全站升级,深度使用了应用级服务发现、Kubernetes 原生服务部署、服务治理等核心能力。来自中仑网络的技术负责人来彬彬对整个 Dubbo3 的选型、升级过程及收益等做了深入总结。

+ 了解更多 {{< /card >}} {{< /cardpane >}} @@ -60,8 +58,16 @@ Apache Dubbo 诞生于阿里巴巴微服务实践之中,在开源之后深受 {{< card header="小米的 Dubbo3 实践" >}} 小米对 Dubbo 多语言版本 Java、Golang 都有着广泛的使用。

了解更多 -{{< /card >}} - + {{< /card >}} + {{< card header="店小蜜" >}} + 阿里云-达摩院-云小蜜对话机器人产品基于深度机器学习技术、自然语言理解技术和对话管理技术,为企业提供多引擎、多渠道、多模态的对话机器人服务。通过全链路升级至开源 Dubbo3.0,云原生网关默认支持 Dubbo3.0,实现透明转发,网关转发 RT 小于 1ms,利用 Dubbo3.0 支持 HTTP2 特性,云原生网关之间采用 mTLS 保障安全。

+ 了解更多 + {{< /card >}} + {{< card header="瓜子" >}} + 瓜子二手车的 Dubbo 实践经验分享

+ 了解更多 + {{< /card >}} +{{< /cardpane >}} \ No newline at end of file diff --git a/content/zh/users/dianxiaomi.md b/content/zh/users/dianxiaomi.md new file mode 100644 index 000000000000..646cb1decb28 --- /dev/null +++ b/content/zh/users/dianxiaomi.md @@ -0,0 +1,118 @@ +--- +type: docs +title: "店小蜜升级 Triple 协议" +linkTitle: "达摩院云小蜜" +weight: 4 +--- + +# 前言 +阿里云-达摩院-云小蜜对话机器人产品基于深度机器学习技术、自然语言理解技术和对话管理技术,为企业提供多引擎、多渠道、多模态的对话机器人服务。17年云小蜜对话机器人在公共云开始公测,同期在混合云场景也不断拓展。为了同时保证公共云、混合云发版效率和稳定性,权衡再三我们采用了1-2个月一个大版本迭代。 +经过几年发展,为了更好支撑业务发展,架构升级、重构总是一个绕不过去的坎,为了保证稳定性每次公共云发版研发同学都要做两件事: + + 1. 梳理各个模块相较线上版本接口依赖变化情况,决定十几个应用的上线顺序、每批次发布比例; + 2. 模拟演练上述1产出的发布顺序,保证后端服务平滑升级,客户无感知; + +上述 1、2 动作每次都需要 2-3 周左右的时间梳理、集中演练,但是也只能保证开放的PaaS API平滑更新; + +控制台服务因为需要前端、API、后端保持版本一致才能做到体验无损(如果每次迭代统一升级API版本开发、协同成本又会非常大),权衡之下之前都是流量低谷期上线,尽量缩短发布时间,避免部分控制台模块偶发报错带来业务问题。针对上面问题,很早之前就考虑过用蓝绿发布、灰度等手段解决,但是无奈之前对话机器人在阿里云内部业务区域,该不再允许普通云产品扩容,没有冗余的机器,流量治理完全没法做。 + +# 迁移阿里云云上 + +带着上面的问题,终于迎来的 2021 年 9 月份,云小蜜将业务迁移至阿里云云上。 + +## Dubbo3 的实践 + +“当时印象最深的就是这张图,虽然当时不知道中间件团队具体要做什么事情,但是记住了两个关键词:三位一体、红利。没想到在2021年底,真真切切享受到了这个红利。” + +![image1](/imgs/v3/users/yunxiaomi-1) + +云小蜜使用的是集团内部的HSF服务框架,需要迁移至阿里云云上,并且存在阿里云云上与阿里内部业务域的互通、互相治理的诉求。云小蜜的公共服务部署在公有云VPC,部分依赖的数据服务部署在内部,内部与云上服务存在RPC互调的诉求,其实属于混合云的典型场景。 +简单整理了下他们的核心诉求,概括起来有以下三点吧:希望尽可能采用开源方案,方便后续业务推广;在网络通信层面需要保障安全性;对于业务升级改造来说需要做到低成本。 + +![image2](/imgs/v3/users/yunxiaomi-2) + +在此场景下,经过许多讨论与探索,方案也敲定了下来 + +- 全链路升级至开源 Dubbo3.0,云原生网关默认支持Dubbo3.0,实现透明转发,网关转发RT小于1ms +- 利用 Dubbo3.0 支持HTTP2特性,云原生网关之间采用 mTLS 保障安全 +- 利用云原生网关默认支持多种注册中心的能力,实现跨域服务发现对用户透明,业务侧无需做任何额外改动 +- 业务侧升级SDK到支持 Dubbo3.0,配置发布 Triple 服务即可,无需额外改动 + +**解决了互通、服务注册发现的问题之后,就是开始看如何进行服务治理方案了** + +# 阿里云云上流量治理 + +迁移至阿里云云上之后,流量控制方案有非常多,比如集团内部的全链路方案、集团内单元化方案等等。 + +## 设计目标和原则 + +1. 要引入一套流量隔离方案,上线过程中,新、旧两个版本服务同时存在时,流量能保证在同一个版本的“集群”里流转,这样就能解决重构带来的内部接口不兼容问题。 +2. 要解决上线过程中控制台的平滑性问题,避免前端、后端、API更新不一致带来的问题。 +3. 无上线需求的应用,可以不参与上线。 +4. 资源消耗要尽量少,毕竟做产品最终还是要考虑成本和利润。 + +## 方案选型 + +1. 集团内部的全链路方案:目前不支持阿里云云上 +2. 集团内单元化方案:主要解决业务规模、容灾等问题,和我们碰到的问题不一样 +3. 搭建独立集群,版本迭代时切集群:成本太大 +4. 自建:在同一个集群隔离新、老服务,保证同一个用户的流量只在同版本服务内流转 + +以RPC为例: + +* 方案一:通过开发保证,当接口不兼容升级时,强制要求升级HSF version,并行提供两个版本的服务; 缺点是一个服务变更,关联使用方都要变更,协同成本特别大,并且为了保持平滑,新老接口要同时提供服务,维护成本也比较高 +* 方案二:给服务(机器)按版本打标,通过RPC框架的路由规则,保证流量优先在同版本内流转 + +## 全链路灰度方案 + +就当1、2、3、4都觉得不完美,一边调研一边准备自建方案5的时候,兜兜绕绕拿到了阿里云 MSE 微服务治理团队[《20分钟获得同款企业级全链路灰度能力》](https://yuque.antfin.com/docs/share/a8df43ac-3a3b-4af4-a443-472828884a5d?#),方案中思路和准备自建的思路完全一致,也是利用了RPC框架的路由策略实现的流量治理,并且实现了产品化(微服务引擎-微服务治理中心),同时,聊了两次后得到几个“支持”,以及几个“后续可以支持”后,好像很多事情变得简单了... + +![image3](/imgs/v3/users/yunxiaomi-3) + +从上图可以看到,各个应用均需要搭建基线(base)环境和灰度(gray)环境,除了流量入口-业务网关以外,下游各个业务模块按需部署灰度(gray)环境,如果某次上线某模块没有变更则无需部署。 + +### 各个中间件的治理方案 + +1. Mysql、ElasticSearch:持久化或半持久化数据,由业务模块自身保证数据结构兼容升级; +2. Redis:由于对话产品会有多轮问答场景,问答上下文是在Redis里,如果不兼容则上线会导致会话过程中的C端用户受影响,因此目前Redis由业务模块自身保证数据结构兼容升级; +3. 配置中心:基线(base)环境、灰度(gray)环境维护两套全量配置会带来较大工作量,为了避免人工保证数据一致性成本,基线(base)环境监听dataId,灰度(gray)环境监听gray.dataId如果未配置gray.dataId则自动监听dataId;(云小蜜因为在18年做混合云项目为了保证混合云、公共云使用一套业务代码,建立了中间件适配层,本能力是在适配层实现) +4. RPC服务:使用阿里云 one agent 基于Java Agent技术利用Dubbo框架的路由规则实现,无需修改业务代码; + +应用只需要加一点配置: + +* 1)linux环境变量 +alicloud.service.tag=gray标识灰度,基线无需打标 +profiler.micro.service.tag.trace.enable=true标识经过该机器的流量,如果没有标签则自动染上和机器相同的标签,并向后透传 +* 2)JVM参数,标识开启MSE微服务流量治理能力** SERVICE_OPTS=**"$**{SERVICE_OPTS}** -Dmse.enable=true"** + +### 流量管理方案 + +流量的分发模块决定流量治理的粒度和管理的灵活程度。 + +对话机器人产品需要灰度发布、蓝绿发布目前分别用下面两种方案实现: + +1. 灰度发布: +部分应用单独更新,使用POP的灰度引流机制,该机制支持按百分比、UID的策略引流到灰度环境 +2. 蓝绿发布: + * 1)部署灰度(gray)集群并测试:测试账号流量在灰度(gray)集群,其他账号流量在基线(base)集群 + * 2)线上版本更新:所有账号流量在灰度(gray)集群 + * 3)部署基线(base)集群并测试:测试账号流量在基线(base)集群,其他账号流量在灰度(gray)集群 + * 4)流量回切到基线(base)集群并缩容灰度(gray)环境:所有账号流量在基线(base)集群 + +## 全链路落地效果 + +上线后第一次发布的效果:“目前各个模块新版本的代码已经完成上线,含发布、功能回归一共大约花费2.5小时,相较之前每次上线到凌晨有很大提升。” +MSE 微服务治理全链路灰度方案满足了云小蜜业务在高速发展情况下快速迭代和小心验证的诉求,通过JavaAgent技术帮助云小蜜快速落地了企业级全链路灰度能力。 +流量治理随着业务发展会有更多的需求,下一步,我们也会不断和微服务治理产品团队,扩充此解决方案的能力和使用场景,比如:rocketmq、schedulerx的灰度治理能力。 + +## 更多的微服务治理能力 + +使用 MSE 服务治理后,发现还有更多开箱即用的治理能力,能够大大提升研发的效率。包含服务查询、服务契约、服务测试等等。这里要特别提一下就是云上的服务测试,服务测试即为用户提供一个云上私网 Postman ,让我们这边能够轻松调用自己的服务。我们可以忽略感知云上复杂的网络拓扑结构,无需关系服务的协议,无需自建测试工具,只需要通过控制台即可实现服务调用。支持 Dubbo 3.0 框架,以及 Dubbo 3.0 主流的 Triple 协议。 + +![image4](/imgs/v3/users/yunxiaomi-4) + +# 结束语 + +最终云小蜜对话机器人团队成功落地了全链路灰度功能,解决了困扰团队许久的发布效率问题。在这个过程中我们做了将部分业务迁移至阿里云云上、服务框架升级至Dubbo3.0、选择MSE微服务治理能力等等一次次新的选择与尝试。“世上本没有路,走的人多了便成了路”。经过我们工程师一次又一次的探索与实践,能够为更多的同学沉淀出一个个最佳实践。我相信这些最佳实践将会如大海中璀璨的明珠般,经过生产实践与时间的打磨将会变得更加熠熠生辉。 + + diff --git a/content/zh/users/fenghuodi.md b/content/zh/users/fenghuodi.md deleted file mode 100644 index fe078e4cf529..000000000000 --- a/content/zh/users/fenghuodi.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -type: docs -title: "烽火递 Dubbo3 实践" -linkTitle: "烽火递" -weight: 6 ---- -Coming Soon ... \ No newline at end of file diff --git a/content/zh/users/guazi.md b/content/zh/users/guazi.md new file mode 100644 index 000000000000..b4db729a76b6 --- /dev/null +++ b/content/zh/users/guazi.md @@ -0,0 +1,174 @@ +--- +type: docs +title: "瓜子二手车 Dubbo 实践" +linkTitle: "瓜子二手车" +weight: 4 +--- + +## 前言 + +  随着瓜子业务的不断发展,系统规模在逐渐扩大,目前在瓜子的私有云上已经运行着数百个dubbo应用,上千个dubbo实例。瓜子各部门业务迅速发展,版本没有来得及统一,各个部门都有自己的用法。随着第二机房的建设,dubbo版本统一的需求变得越发迫切。几个月前,公司发生了一次与dubbo相关的生产事故,成为了公司dubbo版本升级的诱因。 + +  接下来,我会从这次事故开始,讲讲我们这段时间所做的dubbo版本升级的历程以及dubbo后续多机房的方案。 + +## 一、Ephermal节点未及时删除导致provider不能恢复注册的问题修复 + +### 事故背景 + +  在生产环境,瓜子内部各业务线共用一套zookeeper集群作为dubbo的注册中心。2019年9月份,机房的一台交换机发生故障,导致zookeeper集群出现了几分钟的网络波动。在zookeeper集群恢复后,正常情况下dubbo的provider应该会很快重新注册到zookeeper上,但有一小部分的provider很长一段时间没有重新注册到zookeeper上,直到手动重启应用后才恢复注册。 + +### 排查过程 + +  首先,我们统计了出现这种现象的dubbo服务的版本分布情况,发现在大多数的dubbo版本中都存在这种问题,且发生问题的服务比例相对较低,在github中我们也未找到相关问题的issues。因此,推断这是一个尚未修复的且在网络波动情况的场景下偶现的问题。 + +  接着,我们便将出现问题的应用日志、zookeeper日志与dubbo代码逻辑进行相互印证。在应用日志中,应用重连zookeeper成功后provider立刻进行了重新注册,之后便没有任何日志打印。而在zookeeper日志中,注册节点被删除后,并没有重新创建注册节点。对应到dubbo的代码中,只有在`FailbackRegistry.register(url)`的`doRegister(url)`执行成功或线程被挂起的情况下,才能与日志中的情况相吻合。 + +```java + public void register(URL url) { + super.register(url); + failedRegistered.remove(url); + failedUnregistered.remove(url); + try { + // Sending a registration request to the server side + doRegister(url); + } catch (Exception e) { + Throwable t = e; + + // If the startup detection is opened, the Exception is thrown directly. + boolean check = getUrl().getParameter(Constants.CHECK_KEY, true) + && url.getParameter(Constants.CHECK_KEY, true) + && !Constants.CONSUMER_PROTOCOL.equals(url.getProtocol()); + boolean skipFailback = t instanceof SkipFailbackWrapperException; + if (check || skipFailback) { + if (skipFailback) { + t = t.getCause(); + } + throw new IllegalStateException("Failed to register " + url + " to registry " + getUrl().getAddress() + ", cause: " + t.getMessage(), t); + } else { + logger.error("Failed to register " + url + ", waiting for retry, cause: " + t.getMessage(), t); + } + + // Record a failed registration request to a failed list, retry regularly + failedRegistered.add(url); + } + } +``` +  在继续排查问题前,我们先普及下这些概念:dubbo默认使用curator作为zookeeper的客户端,curator与zookeeper是通过session维持连接的。当curator重连zookeeper时,若session未过期,则继续使用原session进行连接;若session已过期,则创建新session重新连接。而ephemeral节点与session是绑定的关系,在session过期后,会删除此session下的ephemeral节点。 + +  继续对`doRegister(url)`的代码进行进一步排查,我们发现在`CuratorZookeeperClient.createEphemeral(path)`方法中有这么一段逻辑:在`createEphemeral(path)`捕获了`NodeExistsException`,创建ephemeral节点时,若此节点已存在,则认为ephemeral节点创建成功。这段逻辑初看起来并没有什么问题,且在以下两种常见的场景下表现正常: + +1. Session未过期,创建Ephemeral节点时原节点仍存在,不需要重新创建 +1. Session已过期,创建Ephemeral节点时原节点已被zookeeper删除,创建成功 + +```java + public void createEphemeral(String path) { + try { + client.create().withMode(CreateMode.EPHEMERAL).forPath(path); + } catch (NodeExistsException e) { + } catch (Exception e) { + throw new IllegalStateException(e.getMessage(), e); + } + } +``` +  但是实际上还有一种极端场景,**zookeeper的Session过期与删除Ephemeral节点不是原子性的**,也就是说客户端在得到Session过期的消息时,Session对应的Ephemeral节点可能还未被zookeeper删除。此时dubbo去创建Ephemeral节点,发现原节点仍存在,故不重新创建。待Ephemeral节点被zookeeper删除后,便会出现dubbo认为重新注册成功,但实际未成功的情况,也就是我们在生产环境遇到的问题。 + +  此时,问题的根源已被定位。定位问题之后,我们与dubbo社区交流,发现考拉的同学也遇到过同样的问题,更确定了这个原因。 + +### 问题的复现与修复 + +  定位到问题之后,我们便开始尝试本地复现。由于zookeeper的Session过期但Ephemeral节点未被删除的场景直接模拟比较困难,我们通过修改zookeeper源码,在Session过期与删除Ephemeral节点的逻辑中增加了一段休眠时间,间接模拟出这种极端场景,并在本地复现了此问题。 + +  在排查问题的过程中,我们发现kafka的旧版本在使用zookeeper时也遇到过类似的问题,并参考kafka关于此问题的修复方案,确定了dubbo的修复方案。在创建Ephemeral节点捕获到`NodeExistsException`时进行判断,若Ephemeral节点的SessionId与当前客户端的SessionId不同,则删除并重建Ephemeral节点。在内部修复并验证通过后,我们向社区提交了issues及pr。 + +  kafka类似问题issues:https://issues.apache.org/jira/browse/KAFKA-1387 + +  dubbo注册恢复问题issues:https://github.com/apache/dubbo/issues/5125 + +## 二、瓜子的dubbo升级历程 + +  上文中的问题修复方案已经确定,但我们显然不可能在每一个dubbo版本上都进行修复。在咨询了社区dubbo的推荐版本后,我们决定在dubbo2.7.3版本的基础上,开发内部版本修复来这个问题。并借这个机会,开始推动公司dubbo版本的统一升级工作。 + +### 为什么要统一dubbo版本 +1. 统一dubbo版本后,我们可以在此版本上内部紧急修复一些dubbo问题(如上文的dubbo注册故障恢复失效问题)。 +2. 瓜子目前正在进行第二机房的建设,部分dubbo服务也在逐渐往第二机房迁移。统一dubbo版本,也是为dubbo的多机房做铺垫。 +3. 有利于我们后续对dubbo服务的统一管控。 +4. dubbo社区目前的发展方向与我们公司现阶段对dubbo的一些诉求相吻合,如支持gRPC、云原生等。 + +### 为什么选择dubbo2.7.3 +1. 在我们之前,携程与dubbo社区合作进行了携程dubbo内部版本的升级,并在社区2.7.3版本上修复了很多兼容性问题。感谢携程的同学帮我们踩坑~ +2. dubbo2.7.3版本在当时虽然是最新的版本,但已经发布了2个月的时间,从社区issues反馈来看,dubbo2.7.3相对dubbo2.7之前的几个版本,在兼容性方面要好很多。 +3. 我们也咨询了dubbo社区的同学,推荐升级版本为2.7.3。 + +### 内部版本定位 + +  基于社区dubbo2.7.3版本开发的dubbo内部版本属于过渡性质的版本,目的是为了修复线上provider不能恢复注册的问题,以及一些社区dubbo2.7.3的兼容性问题。瓜子的dubbo最终还是要跟随社区的版本,而不是开发自已的内部功能。因此我们在dubbo内部版本中修复的所有问题均与社区保持了同步,以保证后续可以兼容升级到社区dubbo的更高版本。 + +### 兼容性验证与升级过程 + +  我们在向dubbo社区的同学咨询了版本升级方面的相关经验后,于9月下旬开始了dubbo版本的升级工作。 +1. **初步兼容性验证** +首先,我们梳理了一些需要验证的兼容性case,针对公司内部使用较多的dubbo版本,与dubbo2.7.3一一进行了兼容性验证。经验证,除dubboX外,dubbo2.7.3与其他dubbo版本均兼容。dubboX由于对dubbo协议进行了更改,与dubbo2.7.3不兼容。 +1. **生产环境兼容性验证** +在初步验证兼容性通过后,我们与业务线合作,挑选了一些重要程度较低的项目,在生产环境对dubbo2.7.3与其他版本的兼容性进行了进一步验证。并在内部版本修复了一些兼容性问题。 +1. **推动公司dubbo版本升级** +在10月初,完成了dubbo兼容性验证后,我们开始在各个业务线推动dubbo的升级工作。截止到12月初,已经有30%的dubbo服务的完成了版本升级。按照排期,预计于2020年3月底前完成公司dubbo版本的统一升级。 + +### 兼容性问题汇总 + +  在推动升级dubbo2.7.3版本的过程整体上比较顺利,当然也遇到了一些兼容性问题: +* **创建zookeeper节点时提示没有权限** + dubbo配置文件中已经配置了zookeeper的用户名密码,但在创建zookeeper节点时却抛出`KeeperErrorCode = NoAuth`的异常,这种情况分别对应两个兼容性问题: + * issues:https://github.com/apache/dubbo/issues/5076 + dubbo在未配置配置中心时,默认使用注册中心作为配置中心。通过注册中心的配置信息初始化配置中心配置时,由于遗漏了用户名密码,导致此问题。 + * issues:https://github.com/apache/dubbo/issues/4991 + dubbo在建立与zookeeper的连接时会根据zookeeper的address复用之前已建立的连接。当多个注册中心使用同一个address,但权限不同时,就会出现`NoAuth`的问题。 + 参考社区的pr,我们在内部版本进行了修复。 + +* **curator版本兼容性问题** + * dubbo2.7.3与低版本的curator不兼容,因此我们默认将curator版本升级至4.2.0 + ```xml + + org.apache.curator + curator-framework + 4.2.0 + + + org.apache.curator + curator-recipes + 4.2.0 + + ``` + * 分布式调度框架elastic-job-lite强依赖低版本的curator,与dubbo2.7.3使用的curator版本不兼容,这给dubbo版本升级工作带来了一定阻塞。考虑到elastic-job-lite已经很久没有人进行维护,目前一些业务线计划将elastic-job-lite替换为其他的调度框架。 +* **openFeign与dubbo兼容性问题** + issues: https://github.com/apache/dubbo/issues/3990 + dubbo的ServiceBean监听spring的ContextRefreshedEvent,进行服务暴露。openFeign提前触发了ContextRefreshedEvent,此时ServiceBean还未完成初始化,于是就导致了应用启动异常。 + 参考社区的pr,我们在内部版本修复了此问题。 +* **RpcException兼容性问题** + dubbo低版本consumer不能识别dubbo2.7版本provider抛出的`org.apache.dubbo.rpc.RpcException`。因此,在consumer全部升级到2.7之前,不建议将provider的`com.alibaba.dubbo.rpc.RpcException`改为`org.apache.dubbo.rpc.RpcException` +* **qos端口占用** + dubbo2.7.3默认开启qos功能,导致一些混部在物理机的dubbo服务升级时出现qos端口占用问题。关闭qos功能后恢复。 +* **自定义扩展兼容性问题** + 业务线对于dubbo的自定义扩展比较少,因此在自定义扩展的兼容性方面暂时还没有遇到比较难处理的问题,基本上都是变更package导致的问题,由业务线自行修复。 +* **skywalking agent兼容性问题** + 我们项目中一般使用skywalking进行链路追踪,由于skywalking agent6.0的plugin不支持dubbo2.7,因此统一升级skywalking agent到6.1。 + +## 三、dubbo多机房方案 + +  瓜子目前正在进行第二机房的建设工作,dubbo多机房是第二机房建设中比较重要的一个话题。在dubbo版本统一的前提下,我们就能够更顺利的开展dubbo多机房相关的调研与开发工作。 + +### 初步方案 + +  我们咨询了dubbo社区的建议,并结合瓜子云平台的现状,初步确定了dubbo多机房的方案。 +1. 在每个机房内,部署一套独立的zookeeper集群。集群间信息不同步。这样就没有了zookeeper集群跨机房延迟与数据不同步的问题。 +1. dubbo服务注册时,仅注册到本机房的zookeeper集群;订阅时,同时订阅两个机房的zookeeper集群。 +1. 实现同机房优先调用的路由逻辑。以减少跨机房调用导致的不必要网络延迟。 + +### 同机房优先调用 + +  dubbo同机房优先调用的实现比较简单,相关逻辑如下: +1. 瓜子云平台默认将机房的标志信息注入容器的环境变量中。 +1. provider暴露服务时,读取环境变量中的机房标志信息,追加到待暴露服务的url中。 +1. consumer调用provider时,读取环境变量中的机房标志信息,根据路由策略优先调用具有相同标志信息的provider。 + +  针对以上逻辑,我们简单实现了dubbo通过环境变量进行路由的功能,并向社区提交了pr。 +  dubbo通过环境变量路由pr: https://github.com/apache/dubbo/pull/5348 diff --git a/content/zh/users/pingan.md b/content/zh/users/pingan.md index 4807373ed8bd..3f3517242807 100644 --- a/content/zh/users/pingan.md +++ b/content/zh/users/pingan.md @@ -4,5 +4,217 @@ title: "平安健康的 Dubbo3 迁移历程" linkTitle: "平安健康" weight: 5 --- +# 1 背景 -Coming Soon ... \ No newline at end of file +我们公司从15年开始就使⽤dubbo做为微服务框架,可以说我们公司的后端应⽤都承载在dubbo之上。当社区推出dubbo3时,我们也⽴刻跟进并做了深⼊调研,发现dubbo3 的应⽤/实例级服务注册和发现能够完美的解决我们当前注册中⼼⾯临的压⼒,解决稳定性和安全性问题。同时dubbo3在服务治理上也做了升级,并且更契合云原⽣架构,⽽且dubbo3能够向下兼容dubbo2,这也将极⼤降低升级的成本和⻛险。 + +通过本⽂我们对公司内部的 Dubbo3 升级过程及收益等做了深⼊总结。值得⼀提 + +的是近期 Dubbo3 官⽹⽂档整体有了本质的提升并且社区承诺短期内⽂档还会投⼊⼤量精⼒完善⽂档,这点对于 Dubbo3 的使⽤和⽤户来说将会是一个福音。 + +# 2 Dubbo3 的核⼼功能介绍 + +dubbo社区关于dubbo3的文档和资料越来越完善,以下是我们从社区引用的一些介绍,主要让读者了解dubbo3目前的状况。 + +## 2.1 下一代云原生服务框架 + +![pingan](/imgs/v3/users/pingan-2.png) + +Dubbo3被社区寄予厚望,将其视为下一代云原生服务框架打造,Dubbo3 提供的核心特性列表,主要包括四部分。 + +- **全新服务发现模型** 。应用粒度服务发现,面向云原生设计,适配基础设施与异构系统;性能与集群伸缩性大幅提升。 +- **下一代 **** RPC ****协议** **Triple** 。基于 HTTP/2 的 Triple 协议,兼容 gRPC;网关穿透性强、多语言友好、支持 Reactive Stream。 +- **统一流量治理模型** 。面向云原生流量治理,SDK、Mesh、VM、Container 等统一治理规则;能够支持更丰富的流量治理场景。 +- **Service Mesh** 。在最新的3.1.0的版本中支持Sidecar Mesh 与 Proxyless Mesh,提供更多架构选择,降低迁移、落地成本。 + +![pingan](/imgs/v3/users/pingan-3.png) + +首先是性能、资源利用率的提升。社区资料显示,升级 Dubbo3 的应用预期能实现单机内存 50% 的下降,对于越大规模的集群效果将越明显,Dubbo3 从架构上支持百万实例级别的集群横向扩展,同时依赖应用级服务发现、Triple协议等可以大大提供应用的服务治理效率和吞吐量。 + +其次, Dubbo3 让业务架构升级变得更容易、更合理,尤其是RPC协议,在 2.x 版本中,web、移动端与后端的通信都要经过网关代理,完成协议转换、类型映射等工作,dubbo3的Triple 协议让这些变得更容易与自然;并通过流式通信模型满足更多的使用场景。 + +最后,得益于 Dubbo3 的完善云原生解决方案,Dubbo3的mesh架构可以帮助业务屏蔽底层云原生基础设施细节,让业务更专注于业务,这也是mesh的最根本的优势。 + +## 2.2 应用级服务发现核心原理 + +![pingan](/imgs/v3/users/pingan-4.png) + +我们从 Dubbo 最经典的工作原理图说起,Dubbo 从设计之初就内置了服务地址发现的能力,Provider 注册地址到注册中心,Consumer 通过订阅实时获取注册中心的地址更新,在收到地址列表后,consumer 基于特定的负载均衡策略发起对 provider 的 RPC 调用。 在这个过程中 + + - 每个 Provider 通过特定的 key 向注册中心注册本机可访问地址; + - 注册中心通过这个 key 对 provider 实例地址进行聚合; + - Consumer 通过同样的 key 从注册中心订阅,以便及时收到聚合后的地址列表; + +![pingan](/imgs/v3/users/pingan-5.png) + +再来看一下Provider向注册中心注册的URL 地址的详细格式,这里把 URL 地址数据划分成了几份: + +- 首先是实例可访问地址,主要信息包含 ip port,是消费端将基于这条数据生成 tcp 网络链接,作为后续 RPC 数据的传输载体。 +- 其次是 RPC 元数据,元数据用于定义和描述一次 RPC 请求,表明这条地址数据是与某条具体的 RPC 服务有关的,它的版本号、分组以及方法相关信息。 +- 下一部分是 RPC 配置数据,部分配置用于控制 RPC 调用的行为,还有一部分配置用于同步 Provider 进程实例的状态,典型的如超时时间、数据编码的序列化方式等。 + +- 最后一部分是自定义的元数据,这部分内容区别于以上框架预定义的各项配置,给了用户更大的灵活性,用户可任意扩展并添加自定义元数据,以进一步丰富实例状态。 + +结合以上对于 Dubbo2 接口级地址模型的分析,以及最开始的 Dubbo 基本原理图,我们可以得出这么几条结论: + +- 第一,地址发现聚合的 key 就是 RPC 粒度的服务。 +- 第二,注册中心同步的数据不止包含地址,还包含了各种元数据以及配置。 +- 得益于 1 与 2,Dubbo 实现了支持应用、RPC 服务、方法粒度的服务治理能力。 + +这就是一直以来 Dubbo2 在易用性、服务治理功能性、可扩展性上强于很多服务框架的真正原因。 + +面对这样的地址数量级放大的问题,在 Dubbo3 架构下,社区认真思考了两个问题: + +- 如何在保留易用性、功能性的同时,重新组织 URL 地址数据,避免冗余数据的出现,让 Dubbo3 能支撑更大规模集群水平扩容? +- 如何在地址发现层面与其他的微服务体系如 Kubernetes、Spring Cloud 打通? + +![pingan](/imgs/v3/users/pingan-6.png) + +最终,社区给出的方案也是非常巧妙和经典。Dubbo3 的应用级服务发现方案设计的基本思路是:地址发现链路上的聚合元素也就是之前提到的 Key 由服务调整为应用,这也是其名称叫做应用级服务发现的由来,与kubernetes和spring cloud的服务注册发现处于同一粒度,能够平滑打通;另外,通过注册中心同步的数据内容上做了大幅精简,只保留最核心的 ip、port 地址数据。 经过上述调整,应用级别服务发现在保持接口级地址模型易用性的同时,实现了地址单条数据大小和总数量的下降。 + +元数据、配置数据以及自定义数据等通过元数据中心或者MetadataService进行同步,且将所有的数据生成一个metadata revision, metadata revision相同则认为元数据等信息相同,通过这种方式来有效降低元数据中心或MetadataService的访问频次。 + +# 3 前期调研 + +了解了 Dubbo3 的核心功能以及应用级服务发现的工作原理后,我们开始进入前期工作阶段。 + +## 3.1 性能压测 + +从社区的资料来看,dubbo3各方面都非常不错,但是我们还得自己检验一把,所以我们先做了dubbo2和dubbo3的性能压测,压测的主要场景在于同步调用,异步场景只做了dubbo3的压测, **以下压测数据和结论仅供参考** 。结果表明dubbo3在性能上面确实做了很多的优化,在相同cpu使用率的情况下,dubbo3的tps是要高于dubbo2的;tps相当的情况下,dubbo3的cpu使用率要低于dubbo2。尤其是dubbo2的接口级与dubbo3的实例级,在tps相当的情况下,dubbo3的cpu使用率要较dubbo2低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.222(内部基于2.5.3版本扩展) | 4C8G | + +测试场景: + +使用的是Dubbo协议,接口没有其它逻辑,直接将输入返回给消费者, 每个场景压30分钟。 + +测试数据(仅供参考): + +| 场景 | 子场景 | 数据包大小 | 类型 | 压力(压力机数量\*线程数) | TPS | P端(cpu 使用率, load) | 平均响应时间 | +| --- | --- | --- | --- | --- | --- | --- | --- | +| dubbo2 \> dubbo2 | 同步、接口级 | 500B | 复杂对象 | 3\*30 | 32568.08 | 70.8%, 3.17 | 2ms | +| dubbo3 \> dubbo3 | 同步、接口级 | 500B | 复杂对象 | 3\*30 | 42790.38 | 68.8%, 2.17 | 2ms | +| dubbo2 \> dubbo2 | 同步、接口级 | 2K | 复杂对象 | 3\*30 | 25929.43 | 68.91%, 2.55 | 3ms | +| dubbo3 \> dubbo3 | 同步、接口级 | 2K | 复杂对象 | 3\*30 | 30446.27 | 61.23%, 2.22 | 2ms | +| dubbo2 \> dubbo2 | 同步、接口级 | 500B | String | 4\*30 | 53866.89 | 89.25%, 4.89 | 2ms | +| dubbo3 \> dubbo3 | 同步、接口级 | 500B | String | 4\*30 | 57424.78 | 74.1%, 2.08 | 2ms | +| dubbo3 \> dubbo3 | P端同步,C端异步、接口级 | 500B | String | 4\*30 | 31136.47 | 47.25%, 1.18 | 3ms | +| dubbo3 \> dubbo3 | 同步、实例级 | 500B | String | 4\*30 | 52363 | 69.53%, 2.55 | 2ms | +| dubbo3 \> dubbo3 | P端同步,C端异步、实例级 | 500B | String | 4\*30 | 29010.51 | 50.3%, 0.32 | 4ms | +| dubbo3 \> dubbo2 | 同步、接口级 | 500B | String | 4\*30 | 37012.61 | 64.17%, 1.59 | 3ms | +| dubbo2 \> dubbo3 | 同步、接口级 | 500B | String | 4\*30 | 45553.7 | 57.01%, 1.96 | 1ms | + +## 3.2 升级前调研 + +做了压测得到dubbo2和dubbo3的压测数据后,我们开始计划将 Dubbo3 引入公司进行试点,此时,我们需要考虑dubbo3与dubbo2的兼容和迁移重构问题,升级目标,以及dubbo3提供有哪些能力支持升级和迁移。 + +### 3.2.1 升级的兼容和迁移重构问题 + +考虑到公司的系统规模,要将dubbo2升级到dubbo3却不是一个简单的过程,尤其是公司的dubbo2版本在原开源版本基础之上做了不少优化和扩展,涵盖了ops服务治理、monitor数据指标监控、服务注册和发现、RPC路由、链路分析、序列化编解码、作为其他基础框架的底层支持等多个方面,同时dubbo3社区也处于非常活跃的状态,我们也希望能够持续享受dubbo社区的技术红利,在这样的背景下不得不考虑三个问题: + +1. 需要解决公司版本的dubbo2与dubbo3的兼容问题; +2. 原有功能的迁移重构问题; +3. 不在dubbo3的源码上做改动,保持和社区版本一致。 + +得益于dubbo 优秀的扩展能力,我们可以通过dubbo 的SPI和IoC模块在dubbo3的基础之上优雅的兼容公司版本的dubbo2,不用改动dubbo3源码,只要研发dubbo3扩展包跟随dubbo3版本的API升级即可,这个升级改动的成本和从社区获取红利相比就显得微不足道了。 + +### 3.2.2 升级目标 + +得到了历史包袱的解决方案,那么就要思考升级的目标了。首先确定的是,最终我们将会采用实例级的服务注册和发现,其次我们目前使用的注册中心是zookeeper,而dubbo社区更推荐使用的注册中心是nacos,而且我们在验证阶段时也暴露过几个在zookeeper上出现而在nacos上没有出现的问题,这也使得我们开始考虑将来是否将注册中心最终也迁移到nacos上。 + +同时, 我们也希望整个迁移过程是平滑、可控的,我们整体方案也要将风险把控做为核心要点考虑,尽可能的做到失败降级、实时可控。 + +而且公司今年在进行战略调整,业务迭代的压力也非常重,所以我们还要尽可能的减少业务研发团队的配合工作量。 + +综上,我们将升级的目标归纳为下面几点: + +1)平滑的从dubbo2升级到dubbo3。 + +2)将接口级服务注册和发现模式平滑的迁移到应用级服务注册和发现模式。 + +3)为后面平滑迁移注册中心做好准备。 + +4)迁移过程可监控、可观测。 + +5)迁移过程要可灰度、可实时管控。 + +6)统一dubbo3的通用配置规范,尽量适配原dubbo2的export和refer方式。 + +### 3.2.3 dubbo3对于迁移的支撑能力 + +前面介绍的是我们的理想,如何把dubbo3的原生设计理念融入到现实情况中呢?以下是我们的相关思考,并在验证过程中。 + +首先dubbo3能够支持在registryUrl上通过参数管理provider和consumer以不同的模式进行服务注册和服务发现,其中核心参数名有: registry-type, registry-protocol-type, register-mode。 + +其次,dubbo3可以支持使用多个注册中心,不同的注册中心通过上面的registryUrl参数控制注册中心的服务注册模式和服务发现模式。而且还可能通过ProviderConfig和ConsumerConfig这两个这两个Config类分别管理provider侧和consumer侧使用的注册中心。在consumer侧,如果有使用多个注册中心,默认会使用ZoneAwareCluster创建的ZoneAwareClusterInvoker来进行负载均衡,从类名上可以看出,该ClusterInvoker是有提供区域感知的能力,观看源码,可以发现,它还提供了preferred的功能,只在相应的registryUrl中添加了preferred=true,这个registryUrl创建的ClusterInvoker就会被优先调用。 + +在同一注册中心进行接口级迁移到实例级的场景中,dubbo3的MigrationInvoker也提供了相应的支持,MigrationInvoker可以根据MigrationRule来控制实例级的RPC流量,并且根据MigrationRuleListener能够实时监听到指定应用的MigrationRule的变更。 + +关于RPC 的监控在dubbo中一直由MonitorFilter和DubboMonitor提供RPC监控数据的收集和上报,收集的数据有消费者的ip端口、提供者的ip端口、应用名称、DubboService、Method、以及成功数、失败数、输入字节数、输出字节数、耗时、并发数等, + +这些能力能够满足基本的迁移工作,结合我们的现状来看,相对升级目标要求的平滑迁移,迁移流量可观测、可灰度、可管控还有一些距离,不过在梳理dubbo3这块能力的时候,也找到了相对简单的扩展方案。到此,对于整体的迁移案也有了一个大致的雏形。 + +# 4 迁移方案 + +方案的设计重点放在"平滑、可控"两点,根据dubbo3的新架构,目前正在验证中的迁移方案示意图如下: + +![pingan](/imgs/v3/users/pingan-7.png) + +从上图可以看出,除了应用外,逻辑上还分了3个区域,分别是注册域、配置管控哉和监控域。注册域主要服务于服务的注册和发现,例如provider在DubboService暴露时,将服务信息和元数据信息上报到注册域的注册中心和元数据中心,consumer通过注册中心和元数据中心来发现服务。配置管控域主要是管理应用配置和迁移流量管控,dubbo3的配置中心天然就支持dubbo3的配置,所以可以流量规则的配置也由dubbo3的配置中心进行维护,dubbo3的DynamicConfigration提供了很多关于动态配置的方法可以直接使用。监控域主要除了原RPC流量的监控外,还细分了迁移流量的监控,在迁移过程中,可以通过监控直观的看到迁移流量的现状,出现问题时,也可以及时报警通知相关人员介入。 + +整个升级过程分为3个阶段: + +第一阶段:将dubbo2升级到dubbo3的接口级,验证功能、兼容性、性能和稳定性 + +第二阶段:接口级和应用级双注册,通过MigrationRule和RegistryMigrationRule管理RPC流量 + +第三阶段:全面切换到应用级,撤掉MigrationRule + +## 4.1 迁移扩展 + +在dubbo3原有能力基础上,也要另外进行扩展以支持平滑迁移的目标,主要如下: + +1. 扩展支持注册中心的迁移可灰度、可管控 + +在dubbo3中,当consumer侧应用了多个注册中心时,默认会通过ZoneAwareCluster创建ZoneAwareClusterInvoker来进行负载均衡,参考基实现可以扩展一个Cluster实现类和一个ClusterInvoker实现将ZoneAwareCluster替换掉,注册中心迁移的流量管理、灰度、降级等能力都在扩展的ClusterInvoker中去实现 + +2. 扩展支持接口级到实例级迁移规则的全局配置管理 + +MigrationRule由MigrationRuleListener通过DynamicConfiguration监听指定的应用的迁移规则,如果一个系统拥有成百上千个微服务应用时,由这种方式去管理,维护成本就太高了,我们借鉴这个方法实现了全局级别的MigrationRule管理能力。 + +3. 扩展迁移流量可观测、可报警 + +dubbo RPC的流量监控已经有MonitorFilter和DubboMonitor实现了,只是MonitorFilter不能识别本次RPC请求的Invoker对象是通过哪个注册中心进行服务发现的,以及该Invoke对象的服务发现模式是接口级还是实例级的。要实现就非常简单了,在consumer侧新增一个ClusterFilter接口和Filter接口去实现这个识别逻辑。 + +4. 迁移组件开关 + +在扩展的最后,要考虑迁移组件下线的问题,即使要下线也几乎不可能再次修改业务工程将迁移组件全部从依赖中删除掉,所以需要通过开关控制迁移组件的功能下线。 + +## 4.2 配置统一管理 + +在升级和迁移过程中,我们可能会随时调整注册中心和迁移规则的配置参数,为减少出错的风险以及业务工程升级改动的工作量,这些公共的配置需要统一管理维护起来,dubbo3的配置中心正常能够把这个任务完美的承接下来。 + +最终我们连配置中心的地址都不让业务方去手动添加,后面又扩展了一个配置加载的组件,通过我们公司内部的配置中心管理维护迁移组件的开关和配置中心的连接地址与超时等配置参数。有了这个组件后,新的应用可以完全不用关心dubbo3和迁移的公共配置,老的应用也减少了这部分公共配置的调整工作量。 + +## 4.3 风险预案 + +dubbo做为我们公司统一的微服务框架,升级过程中任何一点意外,都可能会出现重大的线上故障,给业务造成影响,所以我们整个方案都是在面向失败、面向风险设计的。除了在扩展的迁移组件中实现了主动降级外,也着重考虑了一些极端情况,同时为这些极端情况提供风险预案。线上环境可能会出现各种意想不到的情况,在迁移过程中不希望这些风险会出现,但是一旦这些风险出现,需要有预案知道该如何处理,保证系统快速恢复,不出故障。 + +## 4.4 小结 + +dubbo2是一个优秀的微服务框架,提供的SPI以及Extension机制能够非常方便的让用户去扩展实现想要功能。dubbo3在其基础之上,丰富了不少新的SPI,我们花了很长的时间去设计迁移方案,真正花在迁移组件上的开发时间却非常短。 + +dubbo3整体架构升级调整对于过去的服务注册压力也得到了完美的解决。性能上也做了优化,架构升级后的dubbo3也更适应目前云原生的架构,dubbo 3.1.x 版本支持sidecar和proxyless的mesh方案,而且社区也在准备开源java agent 方式的proxyless,这样就能完美的将微服务架框的framework与数据面解藕,将大大降低微服务框架的维护成本和升级成本,非常期待这一天的到来。 + +# 5 社区协作 + +目前项目仍然在持续升级中,我们跟社区保持着紧密的联系,期间碰到不少问题,都得 + +到了社区开发同学耐⼼解答并最终给予解决。对于要升级 Dubbo3 的⽤户,可以在 社区的Github User Issue(https://github.com/apache/dubbo/issues/9436) 进⾏登记,想参与社区的同学们也可以关注 Dubbo 官⽅公众号(搜索 Apache Dubbo)了解更多社区进展。 \ No newline at end of file diff --git a/content/zh/users/zhonglunwangluo.md b/content/zh/users/zhonglunwangluo.md new file mode 100644 index 000000000000..7409d2e3387f --- /dev/null +++ b/content/zh/users/zhonglunwangluo.md @@ -0,0 +1,60 @@ +--- +type: docs +title: "中伦网络 Dubbo3 升级实践" +linkTitle: "中伦网络" +weight: 4 +--- + +中伦网络在 2022 年完成了服务框架从 Dubbo2 到 Dubbo3 的全站升级,深度使用了应用级服务发现、Kubernetes 原生服务部署、服务治理等核心能力。来自中仑网络的技术负责人来彬彬对整个 Dubbo3 的选型、升级过程及收益等做了深入总结。 + +值得一提的是近期 [Dubbo3 官网文档](https://dubbo.apache.org/zh/) 整体有了本质的提升,并且社区承诺短期内文档还会投入大量精力完善文档,这点对于 Dubbo3 的使用和用户信心提升非常重要。 + +### 一、公司业务与技术架构简介 + +[苏州中仑网络科技有限公司](https://www.zhonglunnet.com/guanyu.html)是一家“专注零售门店增收服务”的公司,一直以“解决中小零售门店经营难的问题”为初心,致力于为零售商户提供门店运营一体化解决方案,帮助零售门店实现增收。中仑网络以零售技术为核心,为零售商户打造出集收银系统、中仑掌柜、微商城、汇邻生活平台、大数据平台、移动支付、智慧农贸、汇邻门店运营服务等为一体的新零售生态体系,实现线上线下全方位融合,为零售商家赋能增收。技术团队在构建之初选取Dubbo 2.5.3+Zookeeper版本构建公司微服务基座支撑公司业务发展,后期同阿里云深度合作整体迁移使用阿里云,使用云原生基础设施ACK(Kubernetes)+MSE(Zookeeper)+Dubbo+PolarDB等构建,实现可动态缩扩容的服务能力。 +伴随合作商扩展3000+,市场遍及300+城市,零售商户30万+,服务覆盖餐饮、茶饮、服装、母婴、烘焙、生鲜、商超、美业、美妆、宠物等多个行业。伴随着领域拓宽、商户量快速增长上升,系统数量和部署节点也迎来了暴增,随之在系统可用性上受到较大挑战:微服务治理能力、微服务地址注册发现,Kubernetes平台服务的无损上下线顺滑度上问题与挑战越来越多。架构图见图一。 + +![image1](/imgs/v3/users/zhonglunwangluo-1.png) + +图一 + +### 二、Dubbo3 升级总结 + +在升级微服务组件技术选型上主要考虑解决以前的痛点:服务治理能力、云原生友好性、服务注册发现,这几个制约业务发展的紧要问题。比较下来Dubbo3架构设计理念与我们较为契合,能较好的满足我们业务发展要求。 + +### 1、服务治理能力 + +Dubbo 3提供丰富的服务治理能力,可实现诸如服务发现、负载均衡、流量调度等服务治理诉求。在使用上我们有两种选择:一、使用Dubbo管理控制台管理配置、二、集成相关API能力到系统。同时Dubbo 扩展性较好,可以在很多功能点(见图二)去定制自己的实现,以改变框架的默认行为来满足自己的业务需求。Dubbo SPI ( Service Provider Interface)将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。这样可以在运行时,动态为接口替换实现类。基于此特性,我们可以很容易的通过 SPI 机制为我们的程序提供拓展功能,如我们在此基础上实现了基于生产和消费者过滤器Filter实现全链路自定义的链路监控;基于路由扩展标签路由方式进行测试环境的隔离方便快速多版本服务测试验证。实操上我们基于生产者注册服务时打标,如原系统A V1版本部署在fat环境上,现在为了测试V2版本,我们将V2版本打标tag=fat-v2;使用端在消费时指定Invocation Attachment 参数,inv.setAttachment(TAG_KEY, routeTag);基于此我们可以方便自测试,同时生产上我们也可以做简单的生产灰度运用。 + +![image2](/imgs/v3/users/zhonglunwangluo-2.png) +图二 + +### 2、云原生友好性 + +Dubbo 在设计上遵循云原生微服务开发理念,微服务支持 Kubernetes平台调度,实现服务生命周期与容器生命周期的对齐,包括 Dubbo 的启动、销毁、服务注册等生命周期事件。中仑网络微服务管理使用的是MSE(Zookeeper),因而我们服务暴露使用需与之对齐。具体操作上我们自定义Startup 启动探针、 Liveness 存活探针、Readiness 就绪探针。项目的正常切换需要保障无损的上下线,在实施中无损上线相对于下线来说会更麻烦点,项目的发布上线过程大体会遵从如下流程:大致分成三个阶段,第一阶段升级少量(如 20% )的实例,并切换少量流量到新版本,完成这个阶段后先暂停升级。经过人工确认之后继续第二个阶段,升级更大比例(如 90% )的实例和流量,再次暂停等待人工确认。最后阶段将全量升级到新版本并验证完毕,从而完成整个发布过程。如果升级期间发现包括业务指标在内的任何异常,例如 CPU 或 memory 异常使用率升高或请求 500 日志过多等情况,可以快速回滚。因为我们使用的是MSE(Zookeeper)服务,dubbo服务自注册在应用启动过程暴露不受Kubernetes 生命周期的控制,出现项目未完全就绪部分服务可被提前可被访问问题。 + +![image3](/imgs/v3/users/zhonglunwangluo-3.png) +图三 + +实施处理上我们主要利用Dubbo Qos指令,初始使用服务不暴露,在应用就绪后调用Qos online指令进行服务上线替换老节点,每次替换的节点数量基于发布策略来制定;下线过程针对需下线节点我们会先使用Qos指令进行下线offline操作等待应用执行完服务,从而进行优雅停机,从实践的效果来看能满足我们的生产需求。 + +### 3、实例级别升级切换 + +相比于 2.x 版本中的基于接口粒度的服务发现机制,3.x 引入了全新的基于应用粒度的服务发现机制,进一步提升了 Dubbo3 在大规模集群实践中的性能与稳定性。此次升级过程中我们也同步引入了配置中心与原数据中心,即将图四置灰部分启用 + +![image4](/imgs/v3/users/zhonglunwangluo-4.png) +图四 + +采用实例级别注册管理,一个应用N个服务,接口级时N服务需监听推送,应用级只关注单实例相关信息。同时引入元数据中心后极大降低接口配置数据信息,减少接口数据传输大小,相关职责配置也更加清晰。根据测试新模型大幅提高系统资源利用率,降低 Dubbo 地址的单机内存消耗,大幅降低注册中心集群的存储与推送压力,上线后稳定性有较大的提升。 + +### 三、总结与展望 + +在中仑网络Dubbo 2升级Dubbo 3的过程中我们也有过一些迟疑,如把接口级换成应用级还是混合注册;Dubbo 3.0新特性新技术在项目中引入的时机与范围。对公司来说大的升级意味风险和不可预知的问题,但同时也能为之带来资源利用率提升、基础功能的扩展与增强,作为技术人员我们需要反复谨慎评估与论证。现在我们已经完成切换所有的业务领域。 + +### 四、Dubbo 社区合作 + +在这里再次感谢Dubbo社区人员的专业、高效,以及对中仑网络架构升级的大力支持,同时很荣幸能够成为一名社区的贡献者,感兴趣的同学可以**加入贡献者钉钉群:31982034**。 + +Dubbo 社区近期筹办了每周一次的微服务纯技术分享,讲解 Dubbo 使用、源码,同时涵盖众多云原生微服务知识,感兴趣的同学可扫码关注。 + + diff --git a/static/imgs/v3/users/pingan-1.png b/static/imgs/v3/users/pingan-1.png new file mode 100644 index 0000000000000000000000000000000000000000..090a431d39ae6babe97ed25cadb2f8ed34aec80c GIT binary patch literal 72772 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