RocketMQ平台的消息灰度方案(2)

简介: RocketMQ平台的消息灰度方案

三、业界MQ灰度方案



(图3.1  灰度调用示意图)


通常,业务灰度只严格地保证RPC服务之间的调用,部分消息灰度流量的流失或错误是可以容忍的,如图3-1所示,V_BFF产生的灰度消息会被V_TRADE的正常版本与灰度版本收到并随机消费,导致部分灰度流量没有进入期望的环境,但整体RPC服务的调用还是隔离了灰度与非灰度环境。当业务对消息消费的逻辑进行了更改,或者不想让灰度的消息影响线上的数据时,MQ的灰度就必须要实现。


由于订阅关系的限制,当前的业界实现的MQ灰度方案都是正常版本与灰度版本使用不同的GroupID来实现。以下的方案均使用了不同的GroupID。


3.1 影子Topic的方案


新建一系列新的Topic来处理隔离灰度的消息。例如对于TOPIC_ORDER会创建TOPIC_ORDER_GRAY来给灰度环境使用。


发送方在发送时,对灰度的消息写入到影子Topic中。消费时,灰度环境只使用灰度的分组订阅灰度的Topic。


3.2 Tag的方案


发送方在发送时,对灰度环境产生的消息的Tag加注灰度标识。消费方,每次灰度版本发布时只订阅灰度Tag的消息,正常的版本订阅非灰度的Tag。


3.3 UserProperty的方案


发送方在发送时,对灰度环境产生的消息的UserProperty加注灰度标识。消费方的客户端需要进行改写,根据UserProperty来过滤,正常的版本会跳过这类消息,灰度的版本会处理灰度消息。


3.4 当前的方案缺陷


以上三种方案各自的优势在这里不做比较,但都存在以下共同的缺陷(也有其它的缺陷或开发诉求,但不致命),无法真正实现灰度状态切换回正常状态时消息不丢失处理,导致整个灰度方案都是从入门到放弃的过程:


  • 因为使用不同的消费组,那么灰度版本验证通过后,如何正确地衔接回原正常版本的消费组的消费位移,做到高效地不丢失信息处理呢?
  • 灰度的消息如何确保准确地消费完毕,做到落在灰度标识的消息做到高效地不丢失信息处理呢?
  • 开启灰度时,灰度消息的位点从那里开始?状态的细节化如何管控?


四、鲁班MQ平台的灰度方案


本质上,MQ灰度问题的核心就是高效地将灰度与非灰度的消息隔离开,消费方按照自己的需求来准确获取到对应版本的消息;当灰度完成后,能够正确地拼接回来消息的位移,做到不丢失处理必要的消息,也就是状态细节上的管理。为了实现这个目的,本方案分别在以下几点进行了改造。


本方案中涉及到的代码为测试代码,主要用于说明方案,实际代码会更精细处理。


4.1 Queue的隔离使用


image.png


(图4.1  Queue的区分使用)


我们已经知道了Queue是topic的实际执行单元,我们的思路就是借助Queue来实现v1(正常)消息、v2(灰度)消息的区分,我们可以固定首尾两条【可配置】Queue专门用来发送与接收灰度的消息,其余的Queue用来发送正常的线上消息。我们使用相同的消费组(也就是和业界的通用方案不一样,我们会使用相同的GroupID),让灰度消费者参与灰度Queue的重平衡,非灰度消费者参与非灰度Queue的重平衡。


这里我们解决了消息的存储隔离问题。


4.2 Broker订阅关系改造


灰度版本往往需要变更Topic或Tag,由于我们没有新增独立的灰度消费组,当灰度版本变更Topic/Tag时,消费组内订阅关系就会不一致,前文也简单解释了订阅关系一致性的原理,我们需要在Broker做出对应的改造,来兼容灰度与非灰度订阅关系不一致的情况。


同一消费组的订阅信息会在维护在ConsumerGroupInfo的subscriptionTable中,可以在ConsumerGroupInfo中增加创建一份graySubscriptionTable用来存储灰度版本的订阅信息,客户端向Broker发送的心跳包会改造成带有自身的灰度标记grayFlag,根据灰度标记grayFlag来选择订阅关系存储在subscriptionTable还是graySubscriptionTable;在拉取消息时,同样向Broker传来grayFlag来选择从subscriptionTable还是graySubscriptionTable中获取对应的订阅信息。


这里我们解决了消费订阅一致性问题。


4.3 Producer的改造


发送方的改造相对简洁,只需确定发送的消息是否为灰度消息,通过实现MessageQueueSelector接口,将灰度消息投递到指定数量的灰度Queue即可。这里我们把用于灰度的grayQueueSize定义到配置中心中去,当前更多是约定使用Broker的指定Queue号作为灰度使用。


TOPIC_V_ORDER共有6条Queue,如图4.2所示,灰度消息只会发送至首尾的0号与5号Queue,非灰度消息则会选择其余的4条Queue发送消息。




(图4.2  发送结果)


这里我们解决了生产者正确投递的问题。


4.4 Consumer的改造


消费方涉及的改造点主要是灰度Queue与非灰度Queue的重平衡分配策略,与各个客户端灰度标记grayFlag的更新与同步。


灰度重平衡策略的核心就是分类处理灰度和非灰度的Queue,要将灰度的Queue分配至灰度ClientID,将非灰度的Queue分配至非灰度的ClientID,因此,在重平衡之前,会通过Namesrv获取同组内的所有客户端clientId对应最新的grayFlag(也就是状态会记录到Namesrv)。


当灰度版本需要变更为线上版本时,各客户端会同步grayFlag到Namesrv,同时,为了避免灰度消息还未消费完成,在更新grayFlag之前会先判断灰度Queue中是否存在未消费的消息,在保证灰度消息消费完成后才会进行grayFlag的更新。


消费者需使用AllocateMessageQueueGray作为重平衡策略,传入灰度Queue的数量,灰度消费者setGrayFlag为true,可以看出只消费了首尾的0号与5号Queue的消息,非灰度消费者setGrayFlag为false,可以看出只会消费中间的4条Queue的消息,在控制台也可以非常清晰的看到Queue的分配结果,grayFlag为true的v2客户端分配到了首尾的Queue,grayFlag为false的v1客户端则分配到了中间的4条Queue。


image.png


image.png


image.png


(图4.3  消费与订阅结果)


当灰度版本需要切换至线上版本时,只需调用updateClientGrayFlag来更新状态即可,可以看出在调用updateClientGrayFlag后,原先v2的两个灰度客户端在消费完灰度Queue的消息后,grayFlag才真正变为false【状态在namesrv保存】,加入到中间的4条非灰度Queue的重平衡中,原先首尾的2条灰度Queue则没有消费者订阅。


image.png



image.png





(图4.4  grayFlag更新)


这里我们解决了状态切换的细节控制处理问题。


4.5 Namesrv的改造


前文提到过,消费者在重平衡时是需要获取组内所有客户端的灰度标识grayFlag,因此,我们需要一个地方来持久化存储这些grayFlag,这个地方是每个消费者都可以访问的,我们选择将这些信息存储在Namesrv。


  • Namesrv相对比较轻量,稳定性很好;
  • 消费者本身就会与Namesrv建立长连接,如果该namesrv挂掉,消费者会自动连接下一个Namesrv,直到有可用连接为止;
  • Broker是实际存储消息的地方,自身运行压力就相对较大,用来做灰度数据的同步一定程度上会加大Broker的压力。


但是Namesrv本身是无状态的节点,节点之间是不会进行信息同步的,灰度数据的一致性需要借助数据库来保证,Namesrv共同访问同一套数据库就好了,数据库持久化存储灰度信息,每次更新v1、v2的灰度状态时,通过Namesrv修改数据库的数据,在每次重平衡之前,再通过Namesrv拉取自己消费组内的所有实例的灰度状态即可。


image.png


(图4.5  Namesrv存储灰度数据示意图)


这里我们解决了状态存储与同步的问题。



相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
7月前
|
消息中间件 安全 物联网
MQTT常见问题之新增自定义主题后平台侧收不到发布的数据如何解决
MQTT(Message Queuing Telemetry Transport)是一个轻量级的、基于发布/订阅模式的消息协议,广泛用于物联网(IoT)中设备间的通信。以下是MQTT使用过程中可能遇到的一些常见问题及其答案的汇总:
|
18天前
|
消息中间件 运维 安全
C5GAME 游戏饰品交易平台借助 RocketMQ Serverless 保障千万级玩家流畅体验
游戏行业蓬勃发展,作为国内领先的 STEAM 游戏饰品交易的服务平台,看 C5GAME 如何利用 RocketMQ Serverless 技术,为千万级玩家提供流畅的游戏体验,同时降低成本并提升运维效率。
C5GAME 游戏饰品交易平台借助 RocketMQ Serverless 保障千万级玩家流畅体验
|
2天前
|
消息中间件 存储 运维
2024最全RabbitMQ集群方案汇总
本文梳理了RabbitMQ集群的几种方案,主要包括普通集群、镜像集群(高可用)、Quorum队列(仲裁队列)、Streams集群模式(高可用+负载均衡)和插件方式。重点介绍了每种方案的特点、优缺点及适用场景。搭建步骤包括安装Erlang和RabbitMQ、配置集群节点、修改hosts文件、配置Erlang Cookie、启动独立节点并创建集群,以及配置镜像队列以提高可用性和容错性。推荐使用Quorum队列与Streams模式,其中Quorum队列适合高可用集群,Streams模式则同时支持高可用和负载均衡。此外,还有Shovel和Federation插件可用于特定场景下的集群搭建。
12 2
|
2天前
|
消息中间件 RocketMQ
2024最全RocketMQ集群方案汇总
在研究RocketMQ集群方案时,发现网上存在诸多不一致之处,如组件包含NameServer、Broker、Proxy等。通过查阅官方文档,了解到v4.x和v5.x版本的差异。v4.x部署模式包括单主、多主、多主多从(异步复制、同步双写),而v5.x新增Local与Cluster模式,主要区别在于Broker和Proxy是否同进程部署。Local模式适合平滑升级,Cluster模式适合高可用需求。不同模式下,集群部署方案大致相同,涵盖单主、多主、多主多从等模式,以满足不同的高可用性和性能需求。
8 0
|
5月前
|
消息中间件 Java 测试技术
消息队列 MQ使用问题之数据流出规则是否支持平台的云RabbitMQ
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
2月前
|
消息中间件 存储 弹性计算
云消息队列 RabbitMQ 版方案评测
本文评估了阿里云《高弹性,低成本,云消息队列 RabbitMQ 实践》方案,从实践原理理解、部署体验、方案优势展现及业务场景匹配四个方面进行了深入分析。文中指出,该方案在解决消息积压、提高系统稳定性、支持弹性伸缩等方面表现优异,但也提出了在组件功能解释、实战案例提供等方面的改进建议,以期帮助用户更好地理解和应用该技术解决方案。
146 0
EMQ
|
5月前
|
物联网 Linux C语言
在 Windows 平台搭建 MQTT 服务
NanoMQ 有着强大的跨平台和可兼容能力,不仅可以用于以 Linux 为基础的各类平台,也为 Windows 平台提供了 MQTT 服务的新选择。
EMQ
124 7
在 Windows 平台搭建 MQTT 服务
|
4月前
|
消息中间件 固态存储 RocketMQ
RocketMQ消息堆积常见场景与处理方案
文章分析了在使用RocketMQ时消息堆积的常见场景,如消费者注册失败或消费速度慢于生产速度,并提供了相应的处理方案,包括提高消费并行度、批量消费、跳过非重要消息以及优化消费代码业务逻辑等。
|
6月前
|
消息中间件 SQL RocketMQ
消息队列 MQ产品使用合集之如何实现灰度
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
6月前
|
消息中间件 RocketMQ
消息队列 MQ产品使用合集之在开源延时消息插件方案中和原生延时消息方案中,同时设置参数是否会出现错乱
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
下一篇
DataWorks