面试官:使用 RocketMQ 怎么进行灰度发布?

news2024/12/25 0:08:15

今天来聊一聊 RocketMQ 的灰度方案。

灰度发布是指在黑与白之间,平滑过渡的一种发布方式。在大流量的系统中,如果一次升级改造范围比较大,或者影响内容不太确定,一般会采用切量的方式进行升级,这样可以减少生产变更带来的影响。

 

如上图,对 ServiceA 这个服务进行升级,采用灰度发布,先升级 Server5,一周后如果没有问题,升级 Server4 和 Server 3,再运行一周没有问题,把剩下两个节点都升级。

上面的案例是一个 RPC 的调用。但如果使用消息队列该怎么做呢?使用消息队列,并不能使用网关来进行流量转发。这里需要分不同场景进行分析。

1 只升级消费者

这是最简单的情况,比如只有消费者修改了消费逻辑,就是 RPC 调用的情况类似,我们只要把消费者进行灰度发布就可以。如下图:

2 生产者也升级

下面是一个订单的实体类,我们新加了一个属性,订单生成时间

public class Order {
    private Long id;
    private Long userId;
    private Long productId;
    private Integer count;
    private BigDecimal payAmount;
    /**订单状态:0:创建中;1:已完结*/
    private Integer status;
    /**新加属性,订单生成时间*/
    private String createTime;
}

消费端的改造是需要对 createTime 这个属性进行处理。

2.1 消费端过滤

在生产者的 Order 类中增加 createTime 属性,如果我们直接使用 createTime 属性来过滤,消费者并不能实现灰度,因为所有的消费者都可能会拉取到带有 createTime 属性的消息。

RocketMQ 中 Message 的定义如下:

public class Message implements Serializable {
    private String topic;
    private int flag;
    private Map<String, String> properties;
    private byte[] body;
    private String transactionId;
}

可以在 properties 属性中增加一个灰度标识,比如生产者发送消息的时候封装如下:

Message msg = buildMessage(topic);
msg.putUserProperty("gray", "true");

注意:也可以在 SendMessageHook 这个钩子函数中定义。通过这种方式可以在消费端新增加一个灰度 Consumer Group,用来对灰度消息则进行消费。如下图:

 

对于灰度 Consumer Group 判断到 gray 属性是 true 时进行消费,而对于普通 Consumer Group,判断到 gray 属性不等于 true 时再进行消费。这里可以借助 RocketMQ 客户端的 FilterMessageHook,代码如下:

defaultMQPushConsumerImpl.registerFilterMessageHook(new FilterMessageHook() {
 @Override
 public String hookName() {
  return "filterHook";
 }

 @Override
 public void filterMessage(FilterMessageContext context) {
  List<MessageExt> messages = context.getMsgList();
                context.setMsgList(messages.stream().filter(m -> StringUtils.equals(m.getProperty("gray"),"true"))
                        .collect(Collectors.toList()));
 }
});

不过这样会有两个问题,灰度和正常的两个 Consumer Group 相当于是广播组

  1. 两个组都要对所有的消息进行拉取,比如本来使用灰度发布计划切 10% 的流量,但实际上全部流量都切过去了,只是根据属性做了判断。这让消费端整体承担了两倍的压力;

  2. 因为两个消费者组都要去 Broker 拉取消息,Broker 的压力也增加了一倍。

2.2 Broker 过滤

2.2.1 使用 tag 过滤

如果一个 Consumer 不订阅一个 Topic 中的全部消息,可以通过 Tag 来过滤。比如一个 Consumer 订阅了 TopicA 这个 Topic 中的 Tag1 和 Tag2 这两个 tag,那这个 Consumer 的订阅关系如下图:

SubscriptionData 这个对象封装了 Topic、tag 以及所订阅 tag 的 hashcode 集合。

Consumer 发送拉取消息请求时,会把订阅关系传给 Broker(Broker 解析成 SubscriptionData 对象),Broker 使用 consumequeue 获取消息时,首先判断判断最后 8 个字节的 tag hashcode 是否在 SubscriptionData 的 codeSet 中,如果不在就跳过,如果存在把消息返回给 Consumer。如下图:

这样可以在灰度 Producer 发送消息时加上 Tag,如下代码:

Message msg = new Message();
msg.setBody("Test");
msg.setTopic("Topic");
msg.setTags("Gray");

而在灰度消费者订阅 Gray 这个 tag。这样就避免了 2.1 节中消息全量拉取的问题。

2.2.2 使用 SQL92 过滤

使用 SQL92 过滤,可以应对更加复杂的场景,不仅可以过滤 Tag,还可以过滤 UserProperty。

比如下面是一个生产者的代码:

Message msg = new Message();
msg.setTopic("testTopic");
msg.setTags("tag1");
msg.putUserProperty("gray","true");

这样消费者初始化的时候,可以定义使用 SQL92 过滤,代码如下:

consumer.subscribe("testTopic",
            MessageSelector.bySql("(TAGS is not null and TAGS in TAGS='''''tag1''''')" +
                "and (gray is not null gray='true')"));

下面是 bySql 的源代码:

public static MessageSelector bySql(String sql) {
 return new MessageSelector(ExpressionType.SQL92, sql);
}

3 总结

本文介绍了 RocketMQ 灰度消息的使用方法,场景比较简单。对于全链路的复杂灰度场景,可以参考使用阿里的微服引擎 MSE。

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

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

相关文章

面试官:MySQL 中 varchar(n) 中 n 最大取值为多少?

前置知识 要回答这个问题&#xff0c;首先我们得先知道 MySQL 存储一条记录的格式长什么样子。 以 Compact 行格式作为例子&#xff0c;它长这样&#xff1a; 可以看到&#xff0c;一条完整的记录分为「记录的额外信息」和「记录的真实数据」两个部分。 这里重点讲讲记录的…

探究L298N模块烧毁的原因

目录 基础介绍 代码思路 基础介绍 L298N电机驱动版主要由两个核心组件构成&#xff1a; L298N 驱动芯片78M05 稳压器型号&#xff1a; L298N封装&#xff1a; Multiwatt15V 描述&#xff1a;电源电压&#xff1a;4.5V~46V 特性&#xff1a;过流保护(OCP)&#xff1b;过热保…

在线教程 | 用「网红项目」DeepSOCIAL 进行社交距离监测

By 超神经 内容一览&#xff1a;YOLO v4 是一个实时的、高精度的目标检测模型&#xff0c;本教程将详细讲解如何基于 YOLO v4 和 SORT 算法&#xff0c;实现在多目标条件下的人群距离检测。 关键词&#xff1a;YOLO v4 SORT 多目标检测 新冠疫情爆发初期&#xff0c;「保持…

VSCODE安装ChatGPT插件

zh1&#xff1a;首先在插件商店搜索ChatGPT中文版 然后点击安装就可以 2&#xff1a;chatGPT插件目前需要登陆账号才能使用&#xff0c;官方介绍下一个版本会有升级(不需要登陆) a:前往 ChatGPT 并登录或注册。 首先要先注册&#xff0c;注册的时候邮箱号可以填国内的也可以用…

利他合作,共赢未来 | 数商云全国渠道代理商招募政策发布

12月2日下午&#xff0c;以“利他合作&#xff0c;共赢未来”为主题的数商云全国渠道代理商招募政策发布会在广州顺利召开&#xff0c;与线上线下来自全国各地区的60家优质厂商共同解读数商云首次公开的招商政策、深入体验数商云全线产品体系&#xff0c;挖掘千亿数字化采购市场…

leecode#有效的电话号码#第十行#上升的温度

题目描述&#xff1a; 给定一个包含电话号码列表&#xff08;一行一个电话号码&#xff09;的文本文件 file.txt&#xff0c;写一个单行 bash 脚本输出所有有效的电话号码。 你可以假设一个有效的电话号码必须满足以下两种格式&#xff1a; (xxx) xxx-xxxx 或 xxx-xxx-xxxx。…

20个有用的Excel数据分析函数(教程含案例)

Microsoft Excel 是一种简单而强大的数据分析工具。Excel 是当今行业中广泛使用的软件应用程序,用于生成报告和业务洞察。Excel 包含超过 450 个函数,并且每年都会添加更多函数。在这里,我们介绍了那些主要用于数据分析的功能。 MAX/MIN MAX和MIN函数顾名思义。MAX将找到范…

零基础CSS入门教程(8)——CSS设置字体

本章目录1.任务目标2.css设置字体3.代码演示4.小结1.任务目标 我们前几个小结学习了&#xff0c;css的选择器&#xff0c;和及基本的改变字体颜色。我们这一小结学习一下设置字体的一些功能 2.css设置字体 (1)font-size这个是设置字体大小&#xff0c;浏览器一般默认字体是1…

剪映专业版常用快捷键(Pr 习惯)

剪映专业版提供了两组常用快捷键&#xff0c;一组适应 Final Cut Pro X 用户的习惯&#xff0c;另一组则是为了适应 Adobe Premiere Pro 用户的习惯。本文列出了剪映专业版&#xff08;v3.6&#xff09;的常用快捷键&#xff0c;以让 Pr 用户快速上手剪映。时间线相关快捷键分割…

无接触体征监测的技术和应用

近年来&#xff0c;由于传感器和微电子技术的飞速发展&#xff0c;基于智能传感器的无接触体征监测技术成为研究热点。尤其是近年来传感器技术和人工智能算法的不断创新&#xff0c;使人们在对人体生理、生化参数等进行监测时能够达到实时、精确和智能化的目的。 智能传感器主要…

软件设计师教程(三)计算机系统知识-计算机体系结构

软件设计师教程 软件设计师教程&#xff08;一&#xff09;计算机系统知识-计算机系统基础知识 软件设计师教程&#xff08;二&#xff09;计算机系统知识-计算机体系结构 安全性、可靠性与系统性能评测基础知识软件设计师教程计算机安全概述计算机的安全等级安全威胁影响数据…

Linux进程的创建

fork是一个系统调用&#xff0c;系统调用的流程&#xff0c;流程的最后会在sys_call_table中找到相应的系统调用sys_fork。&#xff0c;sys_fork的定义如下&#xff1a; SYSCALL_DEFINE0(fork) { ......return _do_fork(SIGCHLD, 0, 0, NULL, NULL, 0); }sys_fork会调用_do_fo…

web大作业:基于html+css+javascript+jquery实现智能分控网站

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

c语言数据结构---链表

我喜欢我的懦弱&#xff0c;痛苦和难堪也喜欢。喜欢夏天的光照&#xff0c;风的气息&#xff0c;蝉的鸣叫&#xff0c;喜欢这些&#xff0c;喜欢得不得了。 ——村上春树《寻羊冒险记》 1.对链表的理解 2.链表每个节点的创建 3.输出链表 链表&#xff1a;顾名思义&#xff0c…

Redis-全面详解(学习总结---从入门到深化)

Redis概述_为什么要用NoSQL 单机Mysql的美好年代 在90年代&#xff0c;一个网站的访问量一般都不大&#xff0c;用单个数据库完全可以轻松应付。在那个时候&#xff0c;更多的都是 静态网页&#xff0c;动态交互类型的网站不多。 遇到问题&#xff1a; 随着用户数的增长&#…

centos7搭建DHCP服务器,实现上网

环境如下&#xff1a; 三台主机&#xff0c;一台centos7&#xff0c;当DNS服务器&#xff0c;一台centos7测试&#xff0c;一台window10测试。 版本centos7.6 三者都是在vmnet8环境下 centos7&#xff08;dns服务器&#xff09;&#xff1a;192.168.139.200 centos&#x…

2小时开发《点球射门游戏》,动画演示思路(下),代码已开源

前沿 首选感谢各位对我这边文章(2小时开发《点球射门游戏》&#xff0c;动画演示思路&#xff08;上&#xff09;&#xff0c;代码已开源&#xff09;的点赞、收藏与支持&#xff0c;今天在这里主要是接上一篇文章&#xff0c;讲一讲游戏界面中的一些动画与逻辑的实现&#xf…

SpringBoot + Elasticsearch 实现模糊查询,批量CRUD,排序,分页,高亮!

一、引入依赖 当前Elasticsearch服务端的版本为8.5.1,此处Spring Data Elasticsearch的版本为2.6.1 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId><version&…

Java中不能在foreach中进行元素的remove和add操作

参考文献&#xff1a;https://juejin.im/post/6844903794795347981 在阿里巴巴Java开发手册中&#xff0c;有这样一条规定&#xff1a; 但是手册中并没有给出具体原因&#xff0c;本文就来深入分析一下该规定背后的思考。 foreach循环 以下实例演示了 普通for循环 和 foreach…

安卓APP源码和设计报告——健身系统

一、设计背景 1.需求分析 对于很多人来说拥有一副好身材能让自己增添不少魅力;对于爱吃而又担心自己发胖的人来说适当的运动健身是最好的选择。移动互联网时代&#xff0c;市场上“约跑”“约健身”健身APP软件成为新时代闺蜜朋友的互动模式&#xff0c;健身热潮的来临&#…