RocketMQ如何安全的批量发送消息❓

优点:

批量发送消息可以提高rocketmq的生产者性能和吞吐量。

使用场景:

  1. 发送大量小型消息时;
  2. 需要降低消息发送延迟时;
  3. 需要提高生产者性能时;

注意事项:

  1. 消息列表的大小不能超过broker设置的最大消息大小;
  2. 消息列表的大小不能超过生产证设置的maxMessageSize 参数,此参数默认为 4MB;
  3. 批量发送消息不支持消息事务;
  4. 如果代码在发送消息列表时发生异常,则可能会发生部分消息发送成功,部分消息发送失败的情况。如果要确保所有消息都已成功发送,则需要增加错误处理逻辑和消息重试机制;

批量发送消息为什么要限制maxMessageSize❓

消息列表的大小不能超过生产者设置的maxMessageSize参数,主要是为了避免消息发送延迟和消息过大导致broker出现性能问题。如果尝试发送大于maxMessageSize的消息,RocketMQ会抛出MessageTooLargeException异常,并且消息不会被发送到broker。

如果开发者在开发时遇到了消息列表大小超过maxMessageSize的情况,可以考虑以下几种处理方式:

    1. 提升maxMessageSize参数的大小,这样可以容纳更大的消息列表。但是,需要注意在提升参数大小时,要考虑到RocketMQ broker的性能和网络带宽等因素。
    2. 考虑将消息列表进行拆分,然后分批发送。这样可以避免一次发送过多的消息。
    3. 计算消息的大小并进行压缩。可以使用一些压缩算法,如 LZ4、Snappy 等,对消息进行压缩,以减小消息的大小。
    4. 对超过 maxMessageSize 的消息进行过滤或其他处理。可以通过业务逻辑对消息进行分组或分类,对超过 maxMessageSize 的消息进行过滤或其他处理,以避免发送超出限制的消息。

代码实现

java 复制代码
package com.resource.sync.rocketmq;


import java.util.Iterator;
import java.util.List;

/**
 * @description:消息分割,在rocketmq中,一次性发送消息的长度不可超过4mb,此时我们需要进行切割,确保消息长度小于4mb
 **/
public class ListSplitter<T> implements Iterator<List<T>> {
    /**
     * 分割数据大小
     */
    private int sizeLimit;

    /**
     * 分割数据列表
     */
    private final List<T> messages;

    /**
     * 分割索引
     */
    private int currIndex;

    public ListSplitter(int sizeLimit, List<T> messages) {
        this.sizeLimit = sizeLimit;
        this.messages = messages;
    }

    @Override
    public boolean hasNext() {
        return currIndex < messages.size();
    }

    @Override
    public List<T> next() {
        int nextIndex = currIndex;
        int totalSize = 0;
        for (; nextIndex < messages.size(); nextIndex++) {
            T t = messages.get(nextIndex);
            totalSize = totalSize + t.toString().length();
            if (totalSize > sizeLimit) {
                break;
            }
        }
        List<T> subList = messages.subList(currIndex, nextIndex);
        currIndex = nextIndex;
        return subList;
    }
}
java 复制代码
    private final int maxMessageSize = 1024 * 1024 * 4;

	/**
     * 消息分割(批量发送)
     */
    private void bulkSendMsg(List<Message<String>> messageList) {
        // 限制数据大小
        ListSplitter splitter = new ListSplitter(maxMessageSize, messageList);
        while (splitter.hasNext()) {
            List<Message> nextList = splitter.next();
            syncBulkSendMessage("topic", nextList);
        }
    }


    /**
     * @param topic
     * @param list
     * @description:发送实时消息(批量)
     */
    public void syncBulkSendMessage(String topic, List<Message> list) {
        SendResult sendResult = null;
        try {
            sendResult = rocketMQTemplate.syncSend(topic, list);
            if (sendResult.getSendStatus() != SendStatus.SEND_OK) {
                log.error("BULK_ROCKET_MQ_DISTRIBUTION_ERROR.RESULT_STATUS:{},MSG_ID:{}", sendResult.getSendStatus(), sendResult.getMsgId());
            }
            if (sendResult.getSendStatus() == SendStatus.SEND_OK) {
                log.info("BULK_SEND_MSG_SUCCESS.MSG_ID:{}", sendResult.getMsgId());
            }

        } catch (Exception e) {
            log.error("BULK_ROCKET_MQ_DISTRIBUTION_ERROR:{}", e);
        }
    }
相关推荐
CryptoRzz3 分钟前
欧美(美股、加拿大股票、墨西哥股票)股票数据接口文档
java·服务器·开发语言·数据库·区块链
杂货铺的小掌柜23 分钟前
apache poi excel 字体数量限制
java·excel·poi
大厂码农老A31 分钟前
你打的日志,正在拖垮你的系统:从P4小白到P7专家都是怎么打日志的?
java·前端·后端
艾菜籽1 小时前
Spring MVC入门补充2
java·spring·mvc
爆更小哇1 小时前
统一功能处理
java·spring boot
程序员鱼皮1 小时前
我造了个程序员练兵场,专治技术焦虑症!
java·计算机·程序员·编程·自学
n8n1 小时前
SpringAI 完全指南:为Java应用注入生成式AI能力
java·后端
不爱编程的小九九2 小时前
小九源码-springboot082-java旅游攻略平台
java·开发语言·旅游
只是懒得想了2 小时前
用C++实现一个高效可扩展的行为树(Behavior Tree)框架
java·开发语言·c++·design-patterns
码农阿树2 小时前
Java 离线视频目标检测性能优化:从 Graphics2D 到 OpenCV 原生绘图的 20 倍性能提升实战
java·yolo·目标检测·音视频