Dubbo 3 StateRouter:下一代微服务高效流量路由

目前的微服务架构中,通常包含服务消费者、服务提供者、注册中心、服务治理四元素,其中服务消费者会向注册中心获取服务提供者的地址列表,并根据路由策略选出需要调用的目标服务提供者地址列表,最后根据负载算法直接调用提供者。当大规模生产环境下,服务消费者从注册中心获取到的服务提供者地址列表过大时,采用传统的路由方式在每次服务调用时都进行大量地址路由选址逻辑,导致服务调用性能低下,资源消耗过多。

云原生场景下,几千、上万乃至十万节点的集群已经不再罕见,如何高效实现这种大规模环境下的选址问题已经成为了必须解决的问题。

流量路由场景

流量路由,顾名思义就是将具有某些属性特征的流量,路由到指定的目标。流量路由是流量治理中重要的一环,多个路由如同流水线一样,形成一条路由链,从所有的地址表中筛选出最终目的地址集合,再通过负载均衡策略选择访问的地址。开发者可以基于流量路由标准来实现各种场景,如灰度发布、金丝雀发布、容灾路由、标签路由等。

路由选址的范式如下:target = rn(…r3(r2(r1(src))))

下面将借着介绍 OpenSergo 对于流量路由所定义的 v1alpha1 标准,来告诉大家实现流量路由所需的技术。

OpenSergo 流量路由 v1alpha1 标准

流量路由规则(v1alpha1) 主要分为三部分:

  • Workload 标签规则 (WorkloadLabelRule):将某一组 workload 打上对应的标签,这一块可以理解为是为 APISIX 的各个上游打上对应的标签
  • 流量标签规则 (TrafficLabelRule):将具有某些属性特征的流量,打上对应的标签
  • 按照 Workload 标签和流量标签来做匹配路由,将带有指定标签的流量路由到匹配的 workload 中

我们可以赋予标签不同的语义,从而实现各个场景下的路由能力。

给 Workload 打标签:

我们对新版本进行灰度时,通常会有单独的环境,单独的部署集。我们将单独的部署集打上 gray 标签(标签值可自定义),标签会参与到具体的流量路由中。

我们可以通过直接在 Kubernetes workload 上打 label 的方式进行标签绑定,如在 Deployment 上打上 http://traffic.opensergo.io/label: gray标签代表灰度。对于一些复杂的 workload 打标场景(如数据库实例、缓存实例标签),我们可以利用 WorkloadLabelRule CRD 进行打标。示例:

apiVersion: traffic.opensergo.io/v1alpha1
kind: WorkloadLabelRule
metadata:name: gray-sts-label-rule
spec:workloadLabels: ['gray']selector:database: 'foo_db'

给流量打标:

假设现在需要将内部测试用户灰度到新版主页,测试用户 uid=12345,UID 位于 X-User-Id header 中,那么只需要配置如下 CRD 即可:

apiVersion: traffic.opensergo.io/v1alpha1
kind: TrafficLabelRule
metadata:name: my-traffic-label-rulelabels:app: my-app
spec:selector:app: my-apptrafficLabel: graymatch:- condition: "=="    # 匹配表达式type: header       # 匹配属性类型key: 'X-User-Id'   # 参数名value: 12345       # 参数值- condition: "=="value: "/index"type: path

通过上述配置,我们可以将 path 为 /index,且 uid header 为 12345 的 HTTP 流量,打上 gray 标,代表这个流量为灰度流量。

讲完场景,下面我们来谈纯技术,我们看看传统的流量路由选址方式是什么样的逻辑。

传统流量路由选址方式

一句话描述就是:每次调用时候根据请求中的条件计算结果地址列表,并遍历当前的地址列表,进行地址过滤。

每个 Router 在每次调用都需要动态计算当前请求需要调用的地址列表的子集,再传递给下一个 Router,伪代码如下:

List<Invoker<T>> route(List<Invoker<T>> invokers, URL url, Invocation invocation) {Tag = invocation.getTag;List<Invoker<T>> targetInvokers = new List<>();for (Invoker invoker: invokers) {if (invoker.match(Tag)) {targetInvokers.add(invoker);}}return targetInvokers;
}

我们分析一下该算法的时间复杂度,发现是O(n)的时间复杂度,每次每个 Router 的 route 调用逻辑都会遍历 invokers 列表,那么当 invokers 数量过大,每次 match 计算的逻辑过大,那么就会造成大量的计算成本,导致路由效率低下。

那么,针对低下效率的计算逻辑,我们是否有什么优化的空间?让我们先来分析与抽象 RPC 的流量路由选址过程。

路由逻辑分析与思考

RPC 的路由选址可以抽象总结为四个过程:

  1. 流量根据流量特性与路由规则选择对应的 Tag
  2. 根据 Tag 选择对应的服务端地址列表
  3. 将上一个 Router 的路由结果地址列表(传入的参数)与符合当前Router的路由结果的地址列表进行集合与操作
  4. 将(3.)的结果传给下一个 Router

其中过程一由于流量一直在变,这个过程的计算必不可少,但是过程二,在绝大多数路由场景下其只会在地址推送于路由规则变化时才有重新计算的必要,如果在每次调用过程中进行大量地址计算,会导致调用性能损耗过大。是否可以把过程二的逻辑进行异步计算并将计算的地址结果进行缓存缓存?避免大量的重复计算。

同时考虑到过程三中的操作属于集合与逻辑,是否有更高效的数据结构?联想到 BitMap,是否可以将地址列表通过 BitMap 形式存储从而使集合与的时间复杂度降低一个数量级。

既然想到了可以优化的 idea,那么让我们来一起设计新的方案并且来实现它!

高效动态选址机制的设计与实现

假设目前有如下 6 条地址,我们需要实现按照 Tag 路由跟按照 AZ 路由的两个能力:

所以我们需要实现两个 Router,假设是 TagRouter 跟 AZRouter,TagRouter 有 3 种 tag 分别是 a、b、c;AZRouter 有三种 az 类型分别是 az_1、az_2、az_3 按照如上假设所示,其实是有 3 * 3 种组合,会存在 3 * 3 * 6 这么多的 URL 引用;假设当前的请求需要去 tag=a&az=az_2,那么按照 Dubbo 原先的方式我们需要在每个 Router 里面遍历一次上一个 Router 计算完成的地址列表,假设存在 M 个 Router、N 条 URL ,那么极端情况下每一次调用需要计算 M*N 次。

那么如果按照我们 StateRouter 路由方式会是怎么一个样子呢?

首先当地址通知下来后,或者路由规则变化时,每个 Router 会先将全量地址按照各自 Router 的路由规则将地址进行计算并将计算结果通过 BitMap 方式存下来;如下图所示:

整体存储架构

我们还是以上述 6 个 URL 为例介绍:

按照路由规则,通过 BitMap 方式进行地址缓存,接下来路由计算时,我们只需从 AddrCache 中取出对应的 addrPool 传递给下一个 Router 即可。

如果当前请求是需要满足 Tag=a & az=az_2,那么我们该如何路由呢?

  • TagRouter 逻辑
  1. 按照流量计算出目标的 Tag,假设是 a
  2. 然后 AddrCache.get(TagRouter).get(a),取出对应的 targetAddrPool
  3. 将上一次传入的 addrPool 与 targetAddrPool 取出 resultAddrPool
  4. 将 resultAddrPool 传入 AZRouter
  • AZRouter 逻辑
  1. 按照流量计算出目标的 Tag,假设是 az_2
  2. 然后 AddrCache.get(AZRouter).get(az_2),取出对应的 targetAddrPool
  3. 将上一次传入的 addrPool 与 targetAddrPool 取出 resultAddrPool
  4. 将 resultAddrPool 为最终路由结果,传递给 LoadBalance

关键源码的伪代码如下:

//List<Invoker<T>>  -> Bitmap
List<Invoker<T>> route(List<Invoker<T>> invokers, Map<Router, Map<Tag, List<Invoker<T>>> cache, URL url, Invocation invocation) {pool = cache.get(this);Tag = invocation.getTag;return pool.get(Tag) & invokers;
}

Dubbo3 使用案例

Dubbo3 在总体性能、集群吞吐量、稳定性等方面相比上一代微服务框架都有了显著的提升,尤其适用于大规模微服务集群实践的场景,StateRouter 即是其中非常重要的一环,该方案通过 Dubbo3 已经在包括阿里之内的众多企业实践验证。

另外提一下,感兴趣的开发者可搜索并加入贡献者群钉钉群 31982034,免费参与每周一次的 Dubbo 技术分享并有机会赢取定制礼品,如果您是 Dubbo3 企业用户欢迎加入钉钉交流群 34129986。

总结

目前 MSE 服务治理的 离群实例摘除、标签路由、金丝雀发布、全链路灰度等功能已经使用该路由方案,经过我们的压测与演练,在 CPU、RT 等方面均有不少提升,以 Demo 应用为例 (服务调用的跳数为 2,下游 30 节点,每个节点 1c2g) 其中调用 RT 提升约 6.7%。

更多服务治理能力与标准的探索

随着分布式服务架构的不断演进带来诸多复杂的稳定性与易用性问题,单一的监控已无法满足架构的演进。在现代微服务架构中,我们需要一些手段来对复杂的微服务架构进行“治理”。微服务治理就是通过全链路灰度、无损上下线、流控降级、异常流量调度、数据库治理等技术手段来减少甚至避免发布和管理大规模应用过程中遇到的稳定性问题,对微服务领域中的各个组件进行治理。服务提供者、消费者、注册中心、服务治理,构成现代微服务架构中重要的几环。

服务治理是微服务改造深入到一定阶段之后的必经之路,在这个过程中我们不断有新的问题出现。

  • 除了全链路灰度,服务治理还有没其他能力?
  • 服务治理能力有没一个标准的定义,服务治理能力包含哪些?
  • 多语言场景下,有无全链路的最佳实践或者标准?
  • 异构微服务如何可以统一治理?

当我们在探索服务治理的过程中,我们在对接其他微服务的时候,我们发现治理体系不同造成的困扰是巨大的,打通两套甚者是多套治理体系的成本也是巨大的。为此我们提出了 OpenSergo 项目。OpenSergo 要解决的是不同框架、不同语言在微服务治理上的概念碎片化、无法互通的问题。

作者:十眠

原文链接

本文为阿里云原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/510456.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

首次全面解析云原生成熟度模型:解决企业「诊断难、规划难、选型难」问题

从“上云”到“云上”原生&#xff0c;云原生提供了最优用云路径&#xff0c;云原生的技术价值已被广泛认可。当前行业用户全面转型云原生已是大势所趋&#xff0c;用户侧云原生平台建设和应用云原生化改造进程正在加速。 然而&#xff0c;云原生复杂的技术栈和传统IT的历史包…

有效预警6要素:亿级调用量的阿里云弹性计算SRE实践

编者按&#xff1a;随着分布式系统和业务需求的飞速发展&#xff0c;监控告警在我们保障系统稳定性和事故快速恢复的全周期中都是至关重要的。9月3号&#xff0c;阿里云弹性计算管控SRE李成武老师(花名佐井)&#xff0c;受「TakinTalks稳定性社区」邀请&#xff0c;在线分享日常…

EMR 重磅发布智能运维诊断系统(EMR Doctor)——开源大数据平台运维利器

大数据运维的挑战—如何保证集群稳定与运行效率 企业级大数据集群通常拥有海量的数据存储、日常运算成干上万的计算任务&#xff0c;需要满足各类上层业务的计算需求。对于这类集群的运维往往充满着挑战&#xff1a;海量的数据、庞杂的组件以及组件之间复杂的依赖关系、对于时…

从中间件到分布式数据库,PolarDB-X 的透明之路

PolarDB-X前身是淘宝内部使用的分库分表中间件TDDL&#xff08;2007年&#xff0c;Java库的形态&#xff09;&#xff0c;早期以DRDS&#xff08;2012年开始研发&#xff0c;2014年上线&#xff0c;分库分表中间件MySQL Proxy的形态&#xff09;的品牌在阿里云上提供服务&#…

阿里云EMAS 移动测试,帮您快速掌握移动端兼容性测试技巧

一、兼容性测试可以查到哪些问题 界面适配问题&#xff0c;确定是否能正常安装、启动。各个页面潜在的崩溃、无响应等问题。应用性能问题&#xff0c;例如启动时间、页面加载时间、功耗等。 二、阿里云兼容性测试工具的功能优势 提供在线录制功能&#xff0c;可视化录制出功能…

零信任策略下K8s安全监控最佳实践(K+)

云原生架构新风险与需求概述 安全风险概述 传统的网络安全架构理念是基于边界的安全架构&#xff0c;企业构建网络安全体系时&#xff0c;首先要做的是寻找安全边界&#xff0c;把网络划分为外网、内网等不同的区域&#xff0c;然后在边界上部署防火墙、入侵检测、WAF等产品。…

ATC‘22顶会论文RunD:高密高并发的轻量级 Serverless 安全容器运行时

编者按&#xff1a;目前的安全容器软件栈 — 包括 host 操作系统中的 cgroup、guest 操作系统和用于函数工作负载的容器 rootfs&#xff0c;都会导致低部署密度和在低并发能力。为此&#xff0c;RunD 作为一种轻量级安全容器运行时&#xff0c;提出了 host-to-guest 的全栈优化…

Dubbo Mesh:从服务框架到统一服务控制平台

Apache Dubbo 是一款 RPC 服务开发框架&#xff0c;用于解决微服务架构下的服务治理与通信问题&#xff0c;官方提供了 Java、Golang 等多语言 SDK 实现。使用 Dubbo 开发的微服务原生具备相互之间的远程地址发现与通信能力&#xff0c; 利用 Dubbo 提供的丰富服务治理特性&…

智能搜索引擎 | 驱动电商业务增长实践

开放搜索是阿里集团搜索业务中台&#xff0c;基于大数据深度学习在线服务体系打造的智能搜索云服务产品。拥有核心引擎、召回排序、搜索引导、充分开放等核心能力&#xff0c;可应用在电商行业、教育行业、内容行业等场景。目前帮助数千家客户搭建自己的搜索业务。 实践案例&a…

通过 Jenkins 构建 CI/CD 实现全链路灰度

本文介绍通过 Jenkins 构建流水线的方式实现全链路灰度功能。在发布过程中&#xff0c;为了整体稳定性&#xff0c;我们总是希望能够用小部分特定流量来验证下新发布应用是否正常。 即使新版本有问题&#xff0c;也能及时发现&#xff0c;控制影响面&#xff0c;保障了整体的稳…

合阔智云核心生产系统切换到服务网格 ASM 的落地实践

背景 合阔智云(http://www.hexcloud.cn) 是专注于为大中型零售连锁行业&#xff0c;提供全渠道业务中/前台产品和解决方案&#xff0c;并建立以消费者为中心的全渠道交易和敏捷供应链的新一代零售运营协同平台。 合阔智云提供了从全渠道交易管理到订单履约再到门店供应链完整…

Serverless 架构下的 AI 应用开发:入门、实战与性能优化

随着时间的推移&#xff0c;Serverless 架构变得越来越火热&#xff0c;凭借着极致弹性、按量付费、低成本运维等特性&#xff0c;在很多领域发挥着越来越重要的作用&#xff1b;机器学习领域在近些年也非常火热&#xff0c;并在越来越多的行业中得到应用。 实际上&#xff0c…

数据变更白屏化利器 - 推送轨迹上线

背景 Zookeeper 可作为注册配置中心&#xff0c;选主&#xff0c;分布式锁等多种场景&#xff0c;随着业务规模的扩大&#xff0c;业务之间的依赖关系逐渐变得复杂&#xff0c;在这种复杂的场景下如果遇到变更推送相关问题&#xff0c;排查起来相当困难&#xff0c;虽然 Zooke…

KubeVela 1.5:灵活框选 CNCF 原子能力打造独特的企业应用发布平台

KubeVela 1.5 于近日正式发布。在该版本中为社区带来了更多的开箱即用的应用交付能力&#xff0c;包括新增系统可观测&#xff1b;新增 Cloud Shell 终端&#xff0c;将 Vela CLI 搬到了浏览器&#xff1b;增强的金丝雀发布&#xff1b;优化多环境应用交付工作流等。进一步提升…

开源小白到核心开发——我与 sealer 的成长故事

个人简介 大家好&#xff0c;我是周欣元&#xff0c;本科就读于杭州师范大学&#xff0c;今年 9 月将去往云南大学进行研究生学习。本科研究方向为 docker 容器在网络攻防中的应用&#xff0c;目前作为 sealer member 加入了核心模块 sealer runtime 的研发工作。 个人主页&a…

全链路灰度新功能:MSE 上线配置标签推送

背景 微服务场景下&#xff0c;全链路灰度作为一种低成本的新功能验证方式&#xff0c;得到了越来越广泛的应用。除了微服务实例和流量的灰度&#xff0c;微服务应用中的配置项也应该具备相应的灰度能力&#xff0c;以应对灰度应用对特殊配置的诉求。 为什么需要配置标签推送…

万节点规模云服务的 SRE 能力建设

背景及现状 系统架构简介 上图为阿里云内部实际使用的系统架构&#xff0c;系统主要用途为实时数据流的计算和存储。使用阿里云的容器服务 ACK 作为系统底座&#xff0c;容器化的部署、发布、管控等全部基于 K8s 标准。使用自己开发的 Gateway service 作为系统流量入口&#…

阿里云 ACK 容器服务生产级可观测体系建设实践

ACK 可观测体系介绍 全景概要介绍 上图为 ACK 可观测体系全景图金字塔&#xff0c;从上至下可分为四层&#xff1a; 最上层是最接近用户业务的 Business Monitoring&#xff0c;包括用户业务的前端的流量、PV、前端性能、JS 响应速度等监控。通过容器服务的 IngressDashboard…

中仑网络全站 Dubbo 2 迁移 Dubbo 3 总结

中仑网络在 2022 年完成了服务框架从 Dubbo 2 到 Dubbo 3 的全站升级&#xff0c;深度使用了应用级服务发现、Kubernetes 原生服务部署、服务治理等核心能力。来自中仑网络的技术负责人来彬彬对整个 Dubbo 3 的选型、升级过程及收益等做了深入总结。 来彬彬&#xff0c;2020 年…

基于 OpenYurt 和 EdgeX 的云边端协同新可能

2022 EdgeX 中国挑战赛暨中关村国际前沿科技创新大赛 EdgeX 专题赛正式拉开帷幕。本次大赛分设两大赛道&#xff1a;医疗、教育、消费行业赛道和能源、工业、供应链赛道。大赛致力于构建一个物联网及边缘计算的学习和分享平台&#xff0c;基于 EdgeX Foundry、OpenYurt 等开源技…