RocketMQ如何保证消息的可靠性

一、如何保证消息不丢失

RocketMQ可能丢失数据的场景如下图:
在这里插入图片描述

生产者发送消息到Broker

生产者发送消息有多种方式,若要保证数据不丢失,根据不同的方式有以下几种方案可以参考:
1、单向模式,这种模式下生产者只是将消息发送到Broker不会等待Broker返回结果,适用于可靠性要求不高的场景下,比如存储报文日志等。
2、同步发送,生产者发送消息之后,会阻塞等待Broker返回结果,如果返回失败,会进行至多2次的将请求轮转到下一个Broker进行重试。若两次都失败返回错误。这种方式有可能造成消息的重复,需要在消费者端做好幂等操作。
3、异步发送,不阻塞,发送方法立即返回结果。在生产者发送消息时,传入一个SendCallback的实现类参数,重写其onSuccess与onException方法,根据业务规则在方法中保证消息得到可靠。
4、RocketMQ支持事务消息,若要保证某条消息不丢失,可以发送一条事务消息,利用事务消息的特性结合具体的业务场景,保证消息的可靠性。

Broker主从复制

Broker支持同步复制和异步复制
在broker.conf 文件中配置BrokerRole,表示当前Broker得角色,可以配置ASYNC_MASTER、 SYNC_MASTER、SLAVE三个值中的一个,ASYNC_MASTER表示这是一个同步复制得Master,当消费者发送一条消息得时候,在所有slave节点都复制完成之后返回。
SYNC_MASTER表示这是一个异步复的Master。
SLAVE表示这是一个从节点。

Broker消息刷盘

生产者在把消息发送到Broker后,先将消息写到PageCache中,然后再持久化到磁盘,次就画额方式Broker支持同步刷盘和异步刷盘
在broker.conf 文件中配置flushDiskType,表示刷盘方式,可以配置SYNC_FLUSH和ASYNC_FLUSH。
SYNC_FLUSH:同步刷盘,在消息写入PageCache中之后, 立即通知刷盘线程刷盘,在刷盘成功之后,再返回生产者消息发送成功。能够保证数据安全,但性能消耗大。
ASYNC_FLUSH:异步刷盘,在消息写入PageCache中之后,立马返回发送成功,在消息积累一定量或者一定时间之后,统一刷盘。可能会存在丢失数据的风险。

消费者消费消息

消息重试机制
消费者中Broker拉取消息之后,只有在返回CONSUME_SUCCESS才算消费成功,如果返回CONSUME_LATER则会根据不同的messageDelayLevel时间再次消费,至多重试16次,如果最终消费失败,消息将会进入死信队列。
死信队列
如果消息重试之后最终消费失败,会进入死信队列,是一个特殊的Topic,名称为:%DLQ%consumerGroup@consumerGroup ,即每个消费者组都有一个死信队列,死信队列对于消费者是不可见的,默认保留三天与正常消息享同。如果消息进入了死信队列,可以在看板中查看该条消息,分析消息进入死信队列的原因,待问题解决之后,可以重新投递消息,正常消费。

二、如何保证消息的幂等

生产者如何保证消息的幂等
当调用链路是A->B->MQ时,如果B->MQ时间超过A->B的超时重试时间时,A重新发起请求,那么可能会导致消息重复发送
解决方案:
1、MQ提供了消息查询功能,在消息发送前查询该条消息是否发送成功即可。
2、消息发送之前查询Redis是否存在该条消息,若不存在,发送消息,并将能否标识该条消息的数据存入Redis。
当消费者拉取消息之后,业务数据已发生变更,但未提交CONSUME_SUCCESS发生宕机,那么生产者会认为消息消费失败了,会触发重试机制,重新发送消息给消费者,如果此时消费者重启,会导致消息重复消费。
解决方案:
消费成功后,将消息的id存入数据库中,作为唯一索引。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值