RocketMq生产常见问题及解决方案(一) 如何保证消息不丢失

1.rocketmq如何保证消息不丢失

1.1 哪些地方会导致消息丢失

在分析如何保证消息不丢失前,我们可以分析一下哪些场景下消息会丢失。

  1. 生产者发送给mq的时候可能因为网络原因导致消息丢失;
  2. mq由于数据是先落到缓存中,然后再从缓存异步刷到磁盘中,可能数据在缓存中还未刷到磁盘时,宕机了,也会导致数据丢失。
  3. 因为网络原因,消费者不一定能够消费到数据。

接下来,我们从这三个方面分析,如何保证消息不丢失。

1.2 生产者如何保证数据一定能够到达mq

1.2.1 方式1:通过同步发送消息+多次重试

实现思路: 将推送到mq消息和本地事务放到同一个事务中,并且如果失败,便多次重试,如果多次重试未果,便回滚事务。

可行性: 因为有本地事务兜底,所以能够保证本地事务的逻辑和mq推送消息的逻辑一定能够同时成功或者失败。

缺点:
1.多次重试可能导致接口缓慢
2.如果中间引入其他中间件,比如redis这些缓存中间件,本地事务就不会生效。

1.2.2 方式2:通过事务消息保证消息不丢失

实现思路:
1.发送half消息到mq中,此时half消息并不能被消费者看到,试探一下mq是否存活。如果half消息发送失败,便会回滚业务逻辑。

2.mq将half消息写入到RMQ_SYS_TRANS_HALF_TOPIC中过后,便会 给业务方返回half消息发送成功或者失败。如果这一步返回失败,业务方会回滚,mq会启动一个定时任务检查未被消费的half消息,并且回调业务方,判断这个half消息是应该回滚还是提交。

3.业务方接收到half响应消息后,执行本地事务逻辑,如果本地事务逻辑执行成功,发送cimmit给mq,执行失败发送rollback给mq。如果是rollback,rocketmq会把half消息写入到OP_TOPIC中,如果是commit,rocketmq会将消息提交到普通的topic中,让消费者消费消息。

4.如果commit或者rollback消息发送失败,此时业务流程已经执行成功,mq会启动一个定时任务检查未被消费的half消息,并且回调业务方,判断这个half消息是应该回滚还是提交。超过15次过后,便会认定这个half消息应该被回滚掉。

执行步骤如下:

1.3 如何保证mq中的数据一定不会丢失

1.开启同步刷盘模式,每次生产者应该是发送消息到mq后,并且刷入到磁盘过后,才返生产成功的消息。开启的代码如下:
 

brokerRole=SYNC_MASTER

2.如果磁盘损坏也可能导致消息丢失,此时可以通过主从部署,当主节点崩溃过后,从节点可以替换主节点成为新的主。

1.4 如何保证消费者一定能够消费到消息

采用同步消费的形式,在消费完成过后,才给mq返回消费的结果。比如ConsumeConcurrentlyStatus.CONSUME_SUCCESS表示消费成功。ConsumeConcurrentlyStatus.RECONSUME_LATER表示消费失败,并且会加入到重试队列中,mq会再次发送消息给消费者,当重试次数超过了16次,便会加入到死信队列。这个时候需要我们进行干预。
因为有重试机制,所以可能会有重复消费的问题,所以我们需要保证消费的幂等性。

1.5 只依靠rocketmq能够保证消息一定不丢失吗?

答案是否定的,以保证消费者一定消费为例,当消息者一直没有消费成功的时候,rocketmq的消费者会进行重试,当超过16次过后,会加入到死信队列,这个时候,我们可以启动一个定时任务去扫描死信队列的内容,做对应的逻辑处理。

所以单靠rocketmq是无法在一些极端场景下保证消息一定不丢失的,需要我们我们做一些额外的逻辑处理,比如监听生产者重试多次依然推送消息到失败,我们回滚我们的业务逻辑等。来保证消息一定不丢失。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值