特色栏目

ASP源码

PHP源码

.NET源码

JSP源码

游戏频道
专题合集
关闭菜单
首页> 交友会员> vivo 微服务架构实践之 Dubbo 性能优化

vivo 微服务架构实践之 Dubbo 性能优化

时间:2026-01-16 16:22:01 作者:互联网

1分钟看图掌握核心观点

图1 VS 图2,您更倾向于哪张图来辅助理解全文呢?欢迎在评论区留言。

一、Dubbo 在 vivo 的演进历程

1.1 vivo 微服务现状

vivo自2015年通过微服务架构升级以赋能业务增长,通过全网治理,于2018年完成了全网Java技术栈RPC框架统一为Dubbo。 目前,该架构高效支撑了5亿用户、覆盖60+地区的业务体量,实现了万级微服务在十万级机器上的稳定运行,日均RPC调用量高达8000亿次。

1.2 Dubbo在vivo的演进历史

Dubbo 是一款 RPC 服务开发框架,主要用于解决微服务架构中的通信与服务治理问题。它提供了服务定义,服务发现、负载均衡、流量管控等丰富能力。vivo在2015年,引入开源社区Dubbo作为Java技术栈RPC框架。而随业务规模发展,业务侧浮现框架版本碎片化现象,产生治理困难,维护成本高等问题。 在19年,vivo引入开源社区2.7.* 版本发布作为第一个基线版本,对业务侧进行了版本收敛。随后发布两个大基线版本,分别为建设三中心分离能力,和应用级注册发现能力。

1.3 Dubbo执行核心链路(概要)

我们先简要介绍一下Dubbo的整体流程。 流程可分为上下两部分。上半部分呈现了由提供方、消费方、注册中心和元数据中心,协同完成的服务注册与引入。 下半部分为调用流程。Dubbo采用微内核与插件化设计,内部多个抽象层次。

总体而言,一次RPC流程可分为两类:

二、Dubbo 路由扩展及优化

2.1 Dubbo路由简介

Dubbo路由是一套基于规则的精细化流量治理组件,其工作流程由服务治理侧向Dubbo下发路由策略,从而确保RPC请求能够被精准的路由至预期的服务实例列表。该机制是支撑灰度发布、机房容灾、环境隔离等流量治理能力的技术基石。 开源版本的Dubbo提供了应用级标签路由、条件路由和脚本路由等核心路由能力。我们在其基础上,扩展实现了接口级标签路由与就近路由两种增强机制。

2.2 就近路由

2.2.1 就近路由背景说明

一般情况下,同机房内部的网络调用平均时延在0.1ms左右,而同城多机房间的平均时延在1ms-5ms,跨地域机房之间的网络时延则更大。 假设内部服务存在大量跨机房调用,尤其针对rt敏感业务,可能因为请求延时的增加,影响服务质量用户体验。 因此Dubbo就近路由应运而生,其可实现RPC过程优先使用同机房进行调用。 可以看到上图,提供方在注册会上报机房信息,消费方调用经过就近路由,只匹配同机房的提供方节点列表。

2.2.2 就近路由场景分析

我们的理想方案如上方所示,是多机房共享注册中心,流量在就近路由的干涉下,在同机房内流转。 但此方案面临下方两个问题: 存在部分业务单机房部署现象,若强制进行同机房调用,会造成消费方无可用提供者。 同时存在多机房非均匀部署现象,若机房间部署规模差异较大,同机房调用可能造成小规模部署机房的业务集群雪崩。

2.2.3 就近路由实践

为解决刚才的问题,我们最终实现如下:

用上边的三个请求举例,在就近路由阶段:

综上,就近路由通过简单的元数据标记和灵活的阈值规则,实现了流量的自动优化与隔离。其改造过程对业务代码无侵入,并带来延迟降低、网络带宽成本下降、稳定性提升的巨大收益。

2.3 标签路由能力说明

接下来是标签路由,标签路由是一种在微服务架构中用于实现流量精细控制的服务治理策略。

其核心思想是通过控制面为服务实例打上自定义标签,标签路由根据消费方调用时指定的标签,将请求流量路由到匹配这些标签的提供方实例。 在Dubbo语义中,Dubbo标签分为动态标签与静态标签:如图所示,我们用通过配置中心下发动态标签,标记gray1包含a节点,标记gray2包含c节点,用于标识两个灰度环境。 而提供方部署时可以自带静态标签,静态标签随Dubbo注册发现流程被消费方在内存缓存。

以三个请求举例:

2.4 我们发现的性能问题

在vivo大规模 Dubbo 提供方集群场景下,高峰期该业务消费方侧应用的整体 CPU 利用率约为60%,而其中负载均衡模块及路由模块的 CPU 占用率竟超过了30%! 通过火焰图分析可以观察到这些问题存在共性 : 相关方法均涉及遍历操作,其时间复杂度与提供方节点数量成正相关。在大规模集群部署环境下,路由与负载均衡模块因遍历计算产生了明显的资源消耗 。

2.4.1 路由优化实践--减少遍历运算

优化思路

2.4.2 路由优化实践

1.引入位图缓存

由火焰图现象发现,无论是就近路由,还是标签路由,筛选流程以及交集计算流程依然存在大量遍历操作带来算力损耗。首先引入缓存减少遍历。

对于标签路由,可以对提供者节点做如下分类: 带动态标签的节点,带静态标签的节点,未打标签的节点,我们可以提前在建立路由元数据的时候,对不同种类节点进行缓存。

我们在标签路由内设置了缓存单元,对上述三类节点,进行了分类缓存。 类似的,在就近路由内,对不同机房的提供者列表,直接进行缓存。 同时,我们以位图形式组织了缓存。

以图中请求为例,全量节点为a,b,c至j,10个节点。 在应用级标签路由z共维护四份缓存:有gray1,gray2,静态标签位图,无标签位图。类似的,接口级维护两份,分别为grayA标签位图,与无标签位图。最后是就近路由,维护机房级别的位图缓存。

请求一从loc1机房发起携带应用级标签gray1,接口级标签garyA。经历应用标签路由与运算,可用列表为a,b,g,经过接口级路由与运算,依然a,b,g。经过就近路由与运算后,只保留ab。由此我们完成了路由执行复杂度从O(n) -> O(1)的挑战。

2.缓存一致性

我们在路由加入epoch戳,用于缓存版本比对。 消费方发起请求时,会携带最新已经以位图形式储存好的提供方列表,以及对应的epoch戳。每到新一级路由时,新路由会比对自身缓存epoch戳与初始epoch是否一致。 如果一致,则证明视图是一致的,直接使用自身位图缓存与上一阶段的位图结果进行与位运算。 如果不一致,则证明当前路由缓存待更新,那么会直接实时用最新路由配置规则与上一阶段的计算的位图结果进行遍历计算。

3.主动缓存更新策略

在提供方持续发布过程中,消费方持续进行服务引入,服务字典侧会同步刷新最新的Invoker列表,并计算新的epoch戳,并将最新的invoker列表更新通知至路由器,用于提前建立最新缓存,同时路由器更新与服务字典一致的epoch。

2.5 路由优化总结

  1. vivo通过建设就近路由能力,显著降低了RT敏感性业务的请求延迟,同时增强了业务的可用性与多机房容灾能力。

  2. 针对路由链,我们从两大方向进行了系统性优化:

    **- 精简链路,**并新增虚拟分组,减少遍历的算力消耗。

    **- 引入位图缓存结构,**大幅加速路由交集计算速度,依托主动缓存更新与 epoch 版本比对机制,保证了缓存视图的强一致性。

优化效果: 随着服务提供方规模不断扩大,CPU 使用率和 TPS 性能提升效果愈发显著。在两千节点规模下,TPS 提升超100%,CPU 利用率也降低27%

三、Dubbo负载均衡扩展及优化

在一次RPC调用经过路由筛选后,消费者端必须从多个服务实例中,选择一个节点来发起请求。这个选择策略,可能直接影响了系统的吞吐量、响应延迟、资源利用率等核心指标。 而Dubbo的负载均衡器,正是承担这一关键决策的核心组件。

3.1 Dubbo负载均衡优化背景介绍

在vivo的互联网业务高速发展过程中,由于持续引入了不同年份、不同供应商的服务器,并考虑到摩尔定律的影响,这些服务器之间存在显著的算力差异。 尽管各实例接收的流量基本一致,但在业务高峰期,实例间CPU利用率表现出明显的不平衡现象。 该现象导致业务集群暴露出若干问题:如整体集群算力利用不充分,低算力机器因负载过高易引发超时,并且频繁触发负载告警被迫人工干预等。

备注: 可以看到Dubbo内置自适应负载策略,它的理念是能够基于服务端的多个实时指标,动态计算节点负载,并选择空闲节点进行调用,实现智能化的弹性负载调度。 但是这里需要说明,vivo建设自适应策略时期较早,同期开源社区自适应策略尚处于提案阶段,只存在初始的社区讨论版本。后续vivo对于自适应策略能力的分析与增强是基于此原始版本思路的进行的。当前开源社区已经提供了正式版本,与vivo实现和原始实现有较大差异。

3.2 社区讨论版自适应负载均衡

3.2.1 社区讨论版自适应负载均衡技术方案

原始方案流程由3部分构成。

  1. 提供方更新自身CPU利用率,每次指标随RPC结果返回。

  2. 消费方异步计算提供方负载,并对负载进行更新并缓存。

  3. 消费方使用P2C算法,这里对P2C做一个简单的介绍:每次负载均衡随机挑选两个节点,并直接选择负载较小的那个节点进行调用。

右侧是消费方采用的埋点指标,包括提供方cpu负载,响应时间等参数。 下边是消费方基于采集指标对负载计算的公式 可以直接简易理解为消费方计算的提供方实例负载值,与实例CPU负载值,在途请求数,RT,呈正相关;与请求成功率,权重配置值呈负相关。

3.2.2 社区讨论版自适应负载均衡压测结果

从结果可以看出,自适应策略使不同算力的机器在流量承载上出现清晰分层,体现了算法基于节点负载进行动态流量调度的有效性。 但也观察到,该版本中CPU利用率存在明显波动,此行为可能会引入服务质量风险。初步分析,利用率震荡原因可能是流量调整机制尚未实现平滑过渡。

3.2.3 社区讨论版波动原因分析

以最简单的双节点场景为例:假设存在节点 P1 和 P2。 初始阶段,P2 负载较高。在提供方将更新的负载指标返回之前,消费方持续将请求集中发往负载较低的 P1,导致 P1 的负载迅速升至峰值,而 P2 此时无调用,负载掉入极低水平。 随后,消费方更新了负载数据,两个节点的负载视图状态发生反转,以此循环往复。

基于上述分析,我们可以从两个关键方向着手优化:

  1. 改进 P2C 的流量分配机制,避免节点在短时间内被集中访问;

  2. 是增强指标平滑流转能力,抑制短期抖动带来的决策干扰,从而提升系统的整体稳定性。

3.3 vivo版自适应负载均衡优化

3.4 vivo自适应负载均衡压测效果展示

左侧从左至右依次展示了随机算法、原始版本自适应策略,以及vivo内部优化后的自适应策略,在双算力配置集群的压测环境中的压测表现: vivo优化版本不仅实现了更优的流量分层,还将各节点CPU利用率收敛至基本一致的水平,并始终保持稳定,使得集群达成高效、高吞吐且稳定运行的理想状态。

右侧呈现了原始策略与vivo版自适应策略,相对随机策略在多项核心指标上的表现,包括TPS、平均RT等,可看出此次优化效果显著,各项指标均有大幅提升。

3.5 vivo自适应负载均衡生产环境使用效果

四、技术成果

在Dubbo路由层面:我们重点解决两大痛点一是路由筛选时的大量遍历操作导致消费端CPU资源浪费,二是跨机房调用对RT敏感业务的性能影响。

针对路由遍历效率问题,我们实施4项优化:

**在负载均衡方面:**我们原先面临着原静态策略难以适配底层设施差异,导致算力利用率低的问题。为此,我们基于社区版本构建了vivo自适应负载均衡能力,重点优化P2C算法并引入权重计算单元,实现流量自适应与平滑调度,最终显著提升服务容量与质量,同时实现降本和节约人力的目标。

五、未来展望

最后是vivo对于Dubbo未来在公司内演进的一些计划与思考:

相关文章

相关应用

热门文章

猜你喜欢

返回顶部