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实现批量消息处理的更多相关文章

  1. MQ系列5:RocketMQ消息的发送模式

    MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 MQ系列3:RocketMQ 架构分析 MQ系列4:NameServer 原理解析 在之前的篇章中,我们学习了RocketMQ的原理, ...

  2. MQ系列6:消息的消费

    MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 MQ系列3:RocketMQ 架构分析 MQ系列4:NameServer 原理解析 MQ系列5:RocketMQ消息的发送模式 在之前 ...

  3. 【SpringBoot MQ 系列】RabbitMq 核心知识点小结

    [MQ 系列]RabbitMq 核心知识点小结 以下内容,部分取材于官方教程,部分来源网络博主的分享,如有兴趣了解更多详细的知识点,可以在本文最后的文章列表中获取原地址 RabbitMQ 是一个基于 ...

  4. 《吃透MQ系列》核心基础全在这里了

    这是<吃透XXX>技术系列的开篇,这个系列的思路是:先找到每个技术栈最本质的东西,然后以此为出发点,逐渐延伸出其他核心知识.所以,整个系列侧重于思考力的训练,不仅仅是讲清楚 What,而是 ...

  5. 【SpringBoot MQ 系列】RabbitListener 消费基本使用姿势介绍

    [MQ 系列]RabbitListener 消费基本使用姿势介绍 之前介绍了 rabbitmq 的消息发送姿势,既然有发送,当然就得有消费者,在 SpringBoot 环境下,消费可以说比较简单了,借 ...

  6. 《吃透MQ系列》之扒开Kafka的神秘面纱

    大家好,这是<吃透 MQ 系列>的第二弹,有些珊珊来迟,后台被好几个读者催更了,实属抱歉! 这篇文章拖更了好几周,起初的想法是:围绕每一个具体的消息中间件,不仅要写透,而且要控制好篇幅,写 ...

  7. MQ系列3:RocketMQ 架构分析

    MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 1 背景 我们前面两篇对主流消息队列的基本构成和技术选型做了详细的分析.从本篇开始,我们会专注当下主流MQ之一的RocketMQ. 从 ...

  8. MQ系列4:NameServer 原理解析

    MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 MQ系列3:RocketMQ 架构分析 1 关于NameServer 上一节的 MQ系列3:RocketMQ 架构分析,我们大致介绍了 ...

  9. MQ系列8:数据存储,消息队列的高可用保障

    MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 MQ系列3:RocketMQ 架构分析 MQ系列4:NameServer 原理解析 MQ系列5:RocketMQ消息的发送模式 MQ系 ...

  10. MQ系列9:高可用架构分析

    MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 MQ系列3:RocketMQ 架构分析 MQ系列4:NameServer 原理解析 MQ系列5:RocketMQ消息的发送模式 MQ系 ...

随机推荐

  1. 曲线艺术编程 coding curves 第十四章 其它曲线(Miscellaneous Curves)

    第十四章 其它曲线(Miscellaneous Curves) 原作:Keith Peters https://www.bit-101.com/blog/2022/11/coding-curves/ ...

  2. 数据库连接池之c3p0-0.9.1.2,线上偶发APPARENT DEADLOCK,如何解?

    前言 本篇其实是承接前面两篇的,都是讲定位线上的c3p0数据库连接池,发生连接泄露的问题. 第二篇讲到,可以配置两个参数,来找出是哪里的代码借了连接后没有归还.但是,在我这边的情况是,对于没有归还的连 ...

  3. ranger2.1.0源码编译以及安装

    ranger2.1.0源码编译以及安装 编译环境准备 环境需求 示例版本 JDK8 Java(TM) SE Runtime Environment (build 1.8.0_231-b11) mave ...

  4. 一:wince 开发环境

    1:下载相关文件,vs2008 可以自行搜索安装 链接:https://pan.baidu.com/s/1b2shwCqmc1o9x-zsy8CmeA 提取码:qing

  5. python3 使用位图排序

    代码 from bitmap import BitMap a=[1,5,3,4,7,8,15,6,9] print(a) bm=BitMap(max(a)) #print(dir(bm)) print ...

  6. 我通过 tensorflow 预测了博客的粉丝数

    前言: 由于最近接触了 tensorflow.js,出于试一下的心态,想通过线性回归预测一下博客的粉丝走向和数量,结果翻车了.虽然场景用错地方,但是整个实战方法用在身高体重等方面的预测还是有可行性,所 ...

  7. Linux系统启动jmeter可视化界面

    目的:方便在Linux系统调试jmeter脚本.操作:Linux启动jmeter可视化界面,不能使用root用户,需要创建新用户,切换到新用户启动jmeter. 1. 创建用户 创建一个新的系统用户. ...

  8. 使用MediatR和FluentValidation实现CQRS应用程序的数据验证

    本文将重点介绍如何通过MediatR的管道功能将FluentValidation集成到项目中实现验证功能. 什么是CQRS? CQRS(Command Query Responsibility Seg ...

  9. 如何使用Grid中的repeat函数

    在本文中,我们将探索 CSS Grid repeat() 函数的所有可能性,它允许我们高效地创建 Grid 列和行的模式,甚至无需媒体查询就可以创建响应式布局. 不要重复自己 通过 grid-temp ...

  10. brpc internal

    brpc 内部实现 thread model pthread 1:1atomic cache同步降低性能 fiber n:1 -> nginx 多核难以扩展, 用户不能做阻塞操作. contex ...