MQ系列15:MQ实现批量消息处理
MQ系列1:消息中间件执行原理
MQ系列2:消息中间件的技术选型
MQ系列3:RocketMQ 架构分析
MQ系列4:NameServer 原理解析
MQ系列5:RocketMQ消息的发送模式
MQ系列6:消息的消费
MQ系列7:消息通信,追求极致性能
MQ系列8:数据存储,消息队列的高可用保障
MQ系列9:高可用架构分析
MQ系列10:如何保证消息幂等性消费
MQ系列11:如何保证消息可靠性传输
MQ系列12:如何保证消息顺序性
MQ系列13:消息大量堆积如何为解决
MQ系列14:MQ如何做到消息延时处理
1 背景
在互联网业务的实际应用场景中,消息的批量处理是非常必要的,因为我们时刻面临着大量数据的并发执行。
例如,我们在一个业务交互的时候会有大量的分支行为需要异步去处理,但是这些动作又是在不同的业务粒度上的,所以我们需要多次调用MQ写入消息,可能有多次的连接和消息发送。
这个写MySQL数据库是一样的,多次建连和写入,跟一次建连和批量数据库,性能是完全不能比的。
所以我们需要有MQ有批量消息的能力来对我们的业务数据进行快速处理。
2 批量消息实现过程
Rocket MQ的批量消息,可以提高消息的吞吐能力和处理效率,降低下游系统的API调用频率,同时对消息服务的稳定性也有帮助。

2.1 批量消息的特点
- 批量消息具有相同的topic。
- 批量消息具有相同的waitStoreMsgOK属性。
- 批量消息不支持延迟消息。
- 批量消息的大小不超过4M(4.4版本之后要求不超过1M)。
2.2 批量消息的使用场景
- 消息的吞吐能力和处理效率:通过将多条消息打包成一批进行发送,可以减少网络传输开销和消息处理的时间,从而提高整体的消息处理效率。
- 下游系统的API调用频率:通过将多条消息合并成一条批量消息进行发送,可以减少下游系统接收和处理消息的次数,从而降低API调用频率,减轻下游系统的负载压力。
2.3 批量消息的发送示例
Rocket MQ提供了批量发送消息的功能,可以通过调用DefaultMQProducer的send()方法,将多条消息以列表的形式发送给指定的topic。
以下是一个简单的示例代码:
DefaultMQProducer producer = new DefaultMQProducer("BatchProducerGroupName_1");
String topic = "BatchSendTest_1";
producer.start();
List<Message> msgs = new ArrayList<>();
msgs.add(new Message(topic, "Tag1", "OrderID-063105013", "Hello world".getBytes()));
msgs.add(new Message(topic, "Tag1", "OrderID-063105014", "Brand".getBytes()));
msgs.add(new Message(topic, "Tag1", "OrderID-063105015", "handsome boy ".getBytes()));
try {
producer.send(msgs);
} catch (Exception e) {
e.printStackTrace();
// 处理异常
}
finally {
// 如果不再发送消息,关闭生产者Producer
producer.shutdown();
}
在以上示例代码中,创建了一个DefaultMQProducer实例,并调用其start()方法启动生产者。
然后构造了一个包含三条消息的列表,通过调用producer的send()方法将列表中的消息发送给指定的topic。
如果消息的总长度可能大于1MB时,这时候最好把消息进行分割,参考下面的代码:
public class ListSplitter implements Iterator<List<Message>> {
private final int SIZE_LIMIT = 1024 * 1024;
private final List<Message> messages;
private int currIndex;
public ListSplitter(List<Message> messages) {
this.messages = messages;
}
@Override public boolean hasNext() {
return currIndex < messages.size();
}
@Override public List<Message> next() {
int nextIndex = currIndex;
int totalSize = 0;
for (; nextIndex < messages.size(); nextIndex++) {
Message message = messages.get(nextIndex);
int tmpSize = message.getTopic().length() + message.getBody().length;
Map<String, String> properties = message.getProperties();
for (Map.Entry<String, String> entry : properties.entrySet()) {
tmpSize += entry.getKey().length() + entry.getValue().length();
}
tmpSize = tmpSize + 20; //for log overhead
if (tmpSize > SIZE_LIMIT) {
//it is unexpected that single message exceeds the SIZE_LIMIT
//here just let it go, otherwise it will block the splitting process
if (nextIndex - currIndex == 0) {
//if the next sublist has no element, add this one and then break, otherwise just break
nextIndex++;
}
break;
}
if (tmpSize + totalSize > SIZE_LIMIT) {
break;
} else {
totalSize += tmpSize;
}
}
List<Message> subList = messages.subList(currIndex, nextIndex);
currIndex = nextIndex;
return subList;
}
}
//then you could split the large list into small ones:
ListSplitter splitter = new ListSplitter(messages);
while (splitter.hasNext()) {
try {
List<Message> listItem = splitter.next();
producer.send(listItem);
} catch (Exception e) {
e.printStackTrace();
// handle the error
}
}
可以看出来,Rocket MQ的批量消息可以提高消息的吞吐能力和处理效率,降低下游系统的API调用频率,是一种优化消息传输和处理的有效手段。
3 总结
- 对于同类型、同特征的消息,可以聚合进行批量发送,减少MQ的连接发送次数,能够显著提升性能。
- 批量发送消息须有相同的topic,相同的waitStoreMsgOK,且不能是延时消息。
MQ系列15:MQ实现批量消息处理的更多相关文章
- MQ系列5:RocketMQ消息的发送模式
MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 MQ系列3:RocketMQ 架构分析 MQ系列4:NameServer 原理解析 在之前的篇章中,我们学习了RocketMQ的原理, ...
- MQ系列6:消息的消费
MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 MQ系列3:RocketMQ 架构分析 MQ系列4:NameServer 原理解析 MQ系列5:RocketMQ消息的发送模式 在之前 ...
- 【SpringBoot MQ 系列】RabbitMq 核心知识点小结
[MQ 系列]RabbitMq 核心知识点小结 以下内容,部分取材于官方教程,部分来源网络博主的分享,如有兴趣了解更多详细的知识点,可以在本文最后的文章列表中获取原地址 RabbitMQ 是一个基于 ...
- 《吃透MQ系列》核心基础全在这里了
这是<吃透XXX>技术系列的开篇,这个系列的思路是:先找到每个技术栈最本质的东西,然后以此为出发点,逐渐延伸出其他核心知识.所以,整个系列侧重于思考力的训练,不仅仅是讲清楚 What,而是 ...
- 【SpringBoot MQ 系列】RabbitListener 消费基本使用姿势介绍
[MQ 系列]RabbitListener 消费基本使用姿势介绍 之前介绍了 rabbitmq 的消息发送姿势,既然有发送,当然就得有消费者,在 SpringBoot 环境下,消费可以说比较简单了,借 ...
- 《吃透MQ系列》之扒开Kafka的神秘面纱
大家好,这是<吃透 MQ 系列>的第二弹,有些珊珊来迟,后台被好几个读者催更了,实属抱歉! 这篇文章拖更了好几周,起初的想法是:围绕每一个具体的消息中间件,不仅要写透,而且要控制好篇幅,写 ...
- MQ系列3:RocketMQ 架构分析
MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 1 背景 我们前面两篇对主流消息队列的基本构成和技术选型做了详细的分析.从本篇开始,我们会专注当下主流MQ之一的RocketMQ. 从 ...
- MQ系列4:NameServer 原理解析
MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 MQ系列3:RocketMQ 架构分析 1 关于NameServer 上一节的 MQ系列3:RocketMQ 架构分析,我们大致介绍了 ...
- MQ系列8:数据存储,消息队列的高可用保障
MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 MQ系列3:RocketMQ 架构分析 MQ系列4:NameServer 原理解析 MQ系列5:RocketMQ消息的发送模式 MQ系 ...
- MQ系列9:高可用架构分析
MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 MQ系列3:RocketMQ 架构分析 MQ系列4:NameServer 原理解析 MQ系列5:RocketMQ消息的发送模式 MQ系 ...
随机推荐
- React学习时,自己拟定的一则小案例(table表格组件,含编辑)
某次在Uniapp群看到有人问uniapp如何操作dom元素. 他想对这张表标红的区域,做dom元素获取,因为产品想让红色色块点击时,成为可编辑,渲染1~4月份之间的行程安排. 于是,有小伙伴说让他用 ...
- ASP.Net Core 项目部署
安装环境 部署环境有两种: .Net Core SDK 包含所有运行时和程序开发包,用于程序开发使用,体积相对较大. .Net Core Runtime 仅用于程序运行,不包含开发包,体积小. 注:部 ...
- 了解web网络基础
TCP/IP 协议:一种规则,规定不同计算机操作系统,硬件之间怎么通信的一种规则 像这样把互联网相关联的协议集合起来总称为TCP/IP协议. TCP/IP分层管理 按照组层次分为以下四层: 应用层:决 ...
- 【xx-job】 定时任务调度
XXL-JOB XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速.学习简单.轻量级.易扩展. 现已开放源代码并接入多家公司线上产品线,开箱即用. 一.任务调度中心 1.1 下载XXL- ...
- 嵌入式低功耗WiFi设备保活功耗分析
(一)嵌入式低功耗设备介绍 在物联网(IoT)领域,设备可以使用以太网和无线网进行网络连接. 以太网: 网络稳定,带宽高,延迟低,但是以太网需要拉网布线,设备安装邻活便利性能差. 无线网络:安装位置灵 ...
- 【原创】xenomai UDD介绍与UDD用户态驱动示例
目录 xenomai UDD与用户态驱动示例 一.UDD介绍 二.UDD原理及框架 1. 内存映射 2. 中断处理 UDD与UIO的区别 3. linux UIO与xenomai UDD框架对比 3. ...
- Vue错误:Cannot read properties of undefined (reading '$router')
解决方案 这是由于this的指向有问题,我们只需要重新声明一下this就可以重新调用了
- 基于C#的窗体阴影效果方案 - 开源研究系列文章
最近在研究C#的Winform窗体的效果,上次介绍了窗体动画效果的博文( 基于C#的无边框窗体动画效果的完美解决方案 - 开源研究系列文章 ),这次将窗体阴影效果的方案进行一个介绍. 找了一下度娘,具 ...
- 1.0 Python 标准输入与输出
python 是一种高级.面向对象.通用的编程语言,由Guido van Rossum发明,于1991年首次发布.python 的设计哲学强调代码的可读性和简洁性,同时也非常适合于大型项目的开发.py ...
- 2.0 Python 数据结构与类型
数据类型是编程语言中的一个重要概念,它定义了数据的类型和提供了特定的操作和方法.在 python 中,数据类型的作用是将不同类型的数据进行分类和定义,例如数字.字符串.列表.元组.集合.字典等.这些数 ...