RocketMQ如何保证消息不丢失
1、哪些环节会有丢消息的可能?
其中,1,2,4三个场景都是跨网络的,而跨网络就肯定会有丢消息的可能。关于3这个环节,通常MQ存盘时都会先写入操作系统的缓存page cache中,然后再由操作系统异步的将消息写入硬盘。这个中间有个时间差,就可能会造成消息丢失。如果服务挂了,缓存中还没有来得及写入硬盘的消息就会丢失。
2、RocketMQ消息零丢失方案
生产者使用事务消息机制保证消息零丢失
1. 生产者使用事务消息机制保证消息零丢失。
RocketMQ的事务消息机制,实际上只保证了整个事务消息的一半,他保证的是生产者将消息发送到broker保证事务一致性,而对下游服务的事务并没有保证。这种方式是分布式事务的一个很好的降级方案。
2. RocketMQ配置同步刷盘+Dledger主从架构保证MQ主从同步时不会丢消息
1、同步刷盘
可以把RocketMQ的刷盘方式 flushDiskType配置成同步刷盘就可以保证消息在刷盘过程中不会丢失了。
2、Dledger的文件同步
使用Dledger技术搭建的RocketMQ集群,Dledger会通过两阶段提交的方式保证文件在主从之间成功同步。
Dledger是由开源组织OpenMessage带入到RocketMQ中的一种高可用集群方案。Dledger的主要作用有两个,一是进行Broker自动选主。二是接管Broker的CommitLog文件写入过程。将单机的文件写入,转为基于多数同意机制的分布式消息写入。基于Raft协议完成了两阶段的数据同步。
3. 消费者端不要使用异步消费机制
正常情况下,消费者端都是需要先处理本地事务,然后再给MQ一个ACK响应,这时MQ就会修改Offset,将消息标记为已消费,从而不再往其他消费者推送消息。所以在Broker的这种重新推送机制下,消息是不会在传输过程中丢失的。
如果异步消费的方式,就有可能造成消息状态返回后消费者本地业务逻辑处理失败造成消息丢失的可能。
4. RocketMQ特有的问题,NameServer挂了如何保证消息不丢失?
如果集群中所有的NameServer节点都挂了,生产者和消费者是立即就无法工作了的。在这种情况下,RocketMQ相当于整个服务都不可用了,那他本身肯定无法给我们保证消息不丢失了。
如果多次尝试发送RocketMQ不成功,可以考虑给(Redis、文件或者内存等)把数据消息缓存下来,然后起一个线程定时的扫描这些失败消息,尝试往RocketMQ发送。这样等RocketMQ的服务恢复过来后,就能第一时间把这些消息重新发送出去。
RocketMQ消息零丢失方案总结
1. 生产者使用事务消息机制。
2. Broker配置同步刷盘+Dledger主从架构。
3. 消费者不要使用异步消费。
4. 整个MQ挂了之后准备降级方案。
使用RocketMQ如何快速处理积压消息?
1、如何确定RocketMQ有大量的消息积压?
对于RocketMQ来说,有个最简单的方式来确定消息是否有积压。那就是使用web控制台,就能直接看到消息的积压情况。在Web控制台的主题页面,可以通过 Consumer管理 按钮实时看到消息的积压情况。也可以通过mqadmin指令在后台检查各个Topic的消息延迟情况。
2、如何处理大量积压的消息?
如果消息不是很重要,那么RocketMQ的管理控制台就直接提供了跳过堆积的功能。
如果Topic下的MessageQueue配置得是足够多的,那每个Consumer实际上会分配多个MessageQueue来进行消费。这个时候,就可以简单的通过增加Consumer的服务节点数量来加快消息的消费,等积压消息消费完了,再恢复成正常情况。最极限的情况是把Consumer的节点个数设置成跟MessageQueue的个数相同。但是如果此时再继续增加Consumer的服务节点就没有用了。
如果Topic下的MessageQueue配置得不够多的话,如果要快速处理积压的消息,可以创建一个新的Topic,配置足够多的MessageQueue。然后把所有消费者节点的目标Topic转向新的Topic,并紧急上线一组新的消费者,只负责消费旧Topic中的消息,并转储到新的Topic中,这个速度是可以很快的。然后在新的Topic上,就可以通过增加消费者个数来提高消费速度了。之后再根据情况恢复成正常情况。