RocketMQ常见问题
rocketmq常见问题
消息丢失
出现消息丢失可能会有三种情况
-
Producer端
-
Broker端
-
Consumer端
Producer保证消息不丢失
-
检查网络延时,如果是网络延迟高,延长收到确认结果的超时时间,默认超时是3秒
-
rocketMQTemplate.getProducer().setSendMsgTimeout(5000);
-
采用同步发送,保证每次发送的消息结果都是正常的
SendResult sendResult1 = rocketMQTemplate.syncSend("base_topic", text1);
-
添加重试次数,默认是3次
//设置同步发送失败后的重试次数为5,4在底层会+1,默认3次 rocketMQTemplate.getProducer().setRetryTimesWhenSendFailed(4);
Broker端保证消息不丢失
-
修改刷盘策略为同步策略,默认情况是异步刷盘
flushDiskType = SYNC_FLUSH
-
集群部署,主从模式,高可用
Consumer端如何保证消息不丢失
- 完全消费后进行手动确认
消息重复消费
- 保证消费消息的幂等性(多次调用和一次调用的效果相同)
- 维护一个消费记录,例如在在消费过程中添加一个唯一ID,在每次消费前都先查询这个消息是否被消费过
消息堆积
消息堆积的主要瓶颈在于消费者的消费能力,消费能力由消费耗时和消费并发度决定的
消费耗时,可能出现的情况有业务代码中出现了死循环,大量递归,调用下游系统出现了异常而没有处理
消费并发度由单节点线程数和节点数量共同决定,其值为单线程数数*节点数,可以调节线程数来提高消费并发度
- 同一个 ConsumerGroup 下,通过增加 Consumer 实例数量来提高并行度(需要注意的是超过订阅队列数的 Consumer 实例无效)。可以通过加机器,或者在已有机器启动多个进程的方式。
- 提高单个 Consumer 的消费并行线程,通过修改参数 consumeThreadNumber、consumeThreadMax实现。
消费者线程数默认为20,最大为65
设置线程数为30
@RocketMQMessageListener( topic = "base_topic",consumerGroup = "defaultGroup", messageModel = MessageModel.BROADCASTING, consumeMode= ConsumeMode.CONCURRENTLY,consumeThreadNumber = 30)
使用批量方式消费提高消费能力
通过设置 consumer的 consumeMessageBatchMaxSize 返个参数,默认是 1,即一次只消费一条消息,例如设置为 10,那么每次消费的消息数小于等于 10。
public class MessageLose implements RocketmqCommonProblemService, RocketMQListener<String>, RocketMQPushConsumerLifecycleListener {
@Resource
private RocketMQTemplate rocketMQTemplate;
@Override
public void prepareStart(DefaultMQPushConsumer consumer) {
//设置批量消费消息的最大次数为10,默认是1
consumer.setConsumeMessageBatchMaxSize(10);
}
}
丢弃非重要的消息
优化每条消息的消费过程