RPC框架的路由策略

news/2024/11/24 6:34:30/

1 为什么选择路由策略?

真实环境的服务提供方以集群提供服务,对服务调用方,就是一个接口会有多个服务提供方同时提供服务,所以RPC每次发起请求时,要从多个服务提供方节点里选择一个用于发请求的节点。这次请求无论发送到集合中的哪个节点上,返回结果都一样。

每次上线应用的时候都不止一台服务器会运行实例,上线涉及变更,只要变更就可能导致原本正常运行的程序异常。

为减少这种风险,一般选择灰度发布应用实例,如先发布少量实例观察是否有异常,再选择发布更多实例还是回滚。但这不好的一点就是,线上一旦问题,影响范围挺大。因为对服务提供方,我们的服务会同时提供给很多调用方来调用,尤其是像一些基础服务的调用方会更复杂,如商品、价格等,一旦刚上线的实例有问题,导致所有的调用方业务都受损。

那对于我们的RPC框架来说,有什么的办法可以减少上线变更导致的风险吗?这就不得不提路由在RPC中的应用。具体好在哪里,怎么实现,我们接着往下看。

2 如何实现路由策略?

由于线上环境复杂,只能降低风险概率,不可能在测试环境彻底验证所有场景。

只能尽量减小上线出问题导致业务受损范围。可先让小部分调用方请求过来进行逻辑验证,没问题后再接入其他调用方,从而实现流量隔离。RPC框架里具体咋实现?

RPC的服务调用方通过服务发现,拿到所有服务提供方的IP地址,可利用这个特点?当选择要灰度验证功能时,让注册中心在推送时区别对待,而不是一股脑把服务提供方的IP地址推送到所有调用方。即注册中心只会把刚上线的服务IP地址推送到选择指定的调用方,而其他调用方不能通过服务发现拿到这个IP地址。

通过服务发现来隔离调用方请求,逻辑上可行,但注册中心在RPC是用来存储数据并保证数据一致性。如果把这种复杂计算逻辑放到注册中心,当集群节点变多,导致注册中心压力大,而且大部分情况都采用开源软件搭建注册中心,要满足这种需求还要二次开发。所以通过影响服务发现来实现请求隔离不划算。

RPC发起真实请求时,有一步是从服务提供方节点集合选一个合适节点(负载均衡),是不是可以在选择节点前加“筛选逻辑”,把符合要求的节点筛选出来。筛选规则就是灰度过程中要验证的规则。

如我们要求新上线的节点只允许某IP可调用,那我们的注册中心会把这条规则下发到服务调用方。在调用方收到规则后,在选择具体要发请求的节点前,会先通过筛选规则过滤节点集合,最后会过滤出一个节点,这个节点就是我们刚才新上线的节点。

这样改造,RPC调用流程变成:

调用流程

这筛选过程在RPC就是“路由策略”,上例是常见的IP路由策略,用于限制可调用服务提供方的IP。

使用IP路由策略后,整个集群的调用拓扑:IP路由调用拓扑

3 参数路由

有IP路由,上线过程中就可做到只让部分调用方请求调用到新上线的实例,相对传统灰度发布,这样做可以把试错成本降到最低。

但有些场景还需更细粒度路由方式。如升级改造应用时,为保证调用方平滑调用新应用逻辑,升级过程中常让新老应用并行运行,然后通过切流,慢慢增大新应用承接流量,直到新应用承担100%且运行一段时间后下线老应用。

流量切换过程,为保证整个流程完整性,须保证某个主题对象的所有请求都使用同一种应用来承接。假设改造的是商品应用,那主题对象肯定是商品ID,在切流量过程中,须保证某商品的所有操作都用新应用(或老应用)完成所有请求的响应。

很显然,IP路由不能满足这需求,因只是限制调用方来源,并不会根据请求参数请求到预设的服务提供方节点。

给所有的服务提供方节点打标签,区分新老应用节点。在服务调用方发生请求的时候,容易拿到请求参数,即例子中的商品ID,根据注册中心下发的规则来判断当前商品ID的请求是过滤掉新应用还是老应用节点。因为规则对所有调用方都一样,保证对应同一个商品ID的请求要么是新应用节点,要么是老应用的节点。

使用参数路由策略后,整个集群的调用拓扑:

参数路由调用拓扑

相比IP路由,参数路由支持的灰度粒度更小,为服务提供方应用提供另一个服务治理的手段。灰度发布功能是RPC路由功能的一个典型应用场景,通过RPC路由策略组合使用,可让服务提供方更加灵活地管理、调用自己的流量,进一步降低上线风险。

4 总结

灰度发布可通过路由功能完成像定点调用、黑白名单等一些高级服务治理功能。在RPC里,不管是哪种路由策略,核心思想都一样:让请求按设定规则发到目标节点,实现流量隔离。

FAQ

我们是做支付系统,需要对接多个银行服务。我们内部将外部服务接口都抽象化一组接口,每次接入只要相应实现即可。每个银行服务,我们会定义一个唯一ID。服务暴露的时候,利用 dubbo group 配置,将group设置为该id,个性化导出。
在银行服务前面有一个路由系统,这个系统会根据上游系统指定id,通过 dubbo 提供 api 调用,调用相应 group 的银行服务。
这应该也是一种利用服务版本路由策略。

路由本质是节点分组、隔离流量,因此不论打标签还是分流等特性都天然适合在路由策略里做。
虽然在调用方(上游)做路由策略选择可用的提供方(下游)集群,是天然符合RPC调用机制的,但是在团队协作上却是反人性的。想一想,当你作为下游服务方,你希望链路中扩展某种路由特性(原生不支持),这时候你需要和你的上游协商并且需要对方优先你或与你同时上线,一般来说对方都是不情愿的,因为对对方而言不仅没有收益还要面临配合你升级带来的风险。因此遇到这种情况时(你作为下游业务方),最好能有全局视角的人来推动不同团队服务的路由策略同时升级,或者能初期设计考虑周全,后期扩展时业务不需要更新部署(例如Dubbo的条件路由、脚本路由等都是可以从第三方写注册中心更新路由策略而无需业务变更)。
扩展新的路由策略不难,新的路由策略上线比较难😂

是的,路由策略最好要抽象成配置信息,可以动态下发。

越到后面越像k8s的服务治理了,基于etcd的服务发现,pod的状态管理与探活,service的负载功能。

路由策略——就是决定走那一条路的判断逻辑。有以下几种方式:
1:通过环境隔离,线上+预发布+压测,当然也有测试+研发
2:服务别名路由,可以控制同机房调用或者流量直走某个分组
3:业务开关这个视具体情况而定,比如:用户黑白名单、四级地址维度切流、配送中心仓库维度切流、订单类型维度切流(大家电、中小件等)配送类型切流(自提、送货上门等)这个就比较灵活了,需要根据自身情况来用,当然,比较依赖配置管理中心,也会有代码逻辑冗余

IP级限制是好理解的,而路由应该是在rpc中相对底层的模块,而在做处理路由策略的时候,还需要应用层的数据,这样的处理感觉不是特别的合理?

规则交给使用者

路由策略怎么和后面的负载均衡连接起来的呢?有形象一点的结构图吗?每个服务集群前面是不是只有一台或一组实现负载均衡的设备?负载均衡设备是怎么区别对待同一个集群里面的新应用和旧应用的呢?

一般是先通过路由筛选,再进行路由选择

并行开发的时候,隔离出不同联调环境。

在多个feature同时开发的时候 可以用路由策略在test环境对某一个服务发布多个版本 在配置中心配置路由规则把来自某一个调用方的请求路由到某一个特定版本的服务上去。即隔离环境👍

通过版本号也可以控制,新服务使用不同的版本号,上线后两个版本都存在,控制部分调用方使用新版本的服务,这种方案可以达到灰度的效果,但是需要调用方配合,没有路由来的方便。

是的,对调用发尽量要做到无感知

我们可以给所有的服务提供方节点都打上标签,用来区分新老应用节点。在服务调用方发生请求的时候,我们可以很容易地拿到请求参数,也就是我们例子中的商品 ID,我们可以根据注册中心下发的规则来判断当前商品 ID 的请求是过滤掉新应用还是老应用的节点。因为规则对所有的调用方都是一样的,从而保证对应同一个商品 ID 的请求要么是新应用的节点,要么是老应用的节点。

就是保证同一个商品ID的所有请求都发送到具体某一个应用,这个应用可以是新应用也可以是老应用,但只能唯一。


http://www.ppmy.cn/news/22889.html

相关文章

Node 多版本管理(清晰明了)

概述 最近学习cloud项目,前端使用到 vue3 ts 等技术,在启动 vue3 项目中需要 node 版本较高(16.15.0),但自己又不想卸载原来的版本,这时使用需要 Node 多版本管理,根据项目官方文档提供的方法…

最全面的SpringBoot教程(四)——数据库连接

前言 本文为 最全面的SpringBoot教程(四)——数据库连接 相关知识,下边将对JDBC连接配置,与使用Druid数据源,从添加依赖到修改配置项再到测试进行详尽介绍~ 📌博主主页:小新要变强 的主页 &…

翻译必考知识点总结+瑞思拜翻译知识点(3,4和5)

1 之一 one of 名词的复数形式 1、《水浒传》(Water Margin)是中国文学四大经典小说之一 Water Margin is one of the four classical novels of(表示的的意思:A of B 是指 B的A) Chinese literature. Water Margin is one of the four classical novels of Chi…

#6队列的实现#

1.队列的概念及其结构 队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先 进先出FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾出队列:进行删除操作的一 端称为队头…

Linux文件与目录的复制、删除与移动

cp(复制文件或目录) cp 【-adfilprsu】 源文件 目标文件 cp 【options】源文件1 源文件2 ......目录 选项与参数: -a:相当于-dr --preserveall的意思,至于dr参考下面说明 -d:若源文件为链接文件的属性&…

【RabbitMQ】Fanout、Direct、Topic、消息转换器

目录 1.发布/订阅 2.Fanout 2.1.声明队列和交换机 2.2.消息发送 2.3.消息接收 2.4.总结 3.Direct 3.1.基于注解声明队列和交换机 3.2.消息发送 3.3.总结 4.Topic 4.1.说明 4.2.消息发送 4.3.消息接收 4.4.总结 5.消息转换器 5.1.测试默认转换器 5.2.配置JSON…

内网渗透(九)之内网信息收集-手动本地信息收集

前言 不管是在外网中还是在内网中,信息收集都是重要的第一步。对于内网中的一台机器,其所处内网的结构是什么样 的、其角色是什么、使用这台机器的人的角色是什么,以及这台机器上安装了什么杀毒软件、这台机器是通过什么方式上网的、这台机器是笔记本电脑还是台式机等问题,都需…

ESP32设备驱动-MMA7361加速度计驱动

MMA7361加速度计驱动 1、MMA7361介绍 MMA7361L 是一款低功耗、薄型电容式微机械加速度计,具有信号调理、1 极低通滤波器、温度补偿、自检、检测线性自由落体的 0g-Detect 和允许在 2 种灵敏度之间进行选择的 g-Select . 零重力偏移和灵敏度是出厂设置的,不需要外部设备。 M…