批量发送消息
生产者
只发送一次,但还是多条消息,这些消息进入同一个队列
DefaultMQProducer producer = new DefaultMQProducer("batch-producer-group");
producer.setNamesrvAddr("127.0.0.1:9876");
producer.start();
producer.maxMessageSize(4194304); // 消息数据大小,默认是 4M(4.9.6版本),早期是1M
// 构建消息
List<Message> msgs = Arrays.asList(
new Message("batchTopic", "我是一组消息的A消息".getBytes()),
new Message("batchTopic", "我是一组消息的B消息".getBytes()),
new Message("batchTopic", "我是一组消息的C消息".getBytes())
);
// send 被重载过,支持传入一个 List<Message>,虽然多个消息,但是是一次发送,所以这批消息将进入同一个队列中
SendResult send = producer.send(msgs);
System.out.println(send);
producer.shutdown();
Broker 处理
Broker 接收到批量消息后:
- 将批量消息解包为单条消息
- 分别存储到 CommitLog 中(是个文件,每个消息都会写入到这个文件,包含每个消息的Topic、Tag、Body等属性)
- 为每条消息构建索引(所有消息都放到这一个文件中,构建索引为了快速定位每条消息)
消费者
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("batch-consumer-group");
consumer.setNamesrvAddr("127.0.0.1:9876");
consumer.subscribe("batchTopic", "*");
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
// 会打印 3 次(一次发送多个消息,消费时还是一条一条的来消费)
System.out.println("收到消息了" + new Date());
System.out.println(msgs.size());
System.out.println(new String(msgs.get(0).getBody()));
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
consumer.start();
注意事项
- 默认最大批量大小为 4MB(可通过
maxMessageSize
参数配置),单条消息(非批量)也受同样的限制 - 单个批次消息数量建议不超过 32 条(过多会影响消费速度)
- 批量消息发送失败时,整个批次都会失败
- 批量消息不支持延迟消息和事务消息