RocketMQ在交易支付场景如何做到消息零丢失?

消费流程图

 

 消息丢失的三个场景

场景一:生产者生产消息发送到RocketMQ,出现网络抖动或通信异常等问题

场景二:RocketMQ接收到了消息之后,持久化到磁盘(两步,先写入到os cache中减少磁盘io,再异步刷入磁盘),断电或宕机之后会造成数据的丢失
场景三:消费者从RocketMQ中获取消息消费,消费未完成旧通知RocketMQ已经将消息消费,此时消费者宕机,数据丢失

 

 保证消息的零丢失

 

 

场景一:使用RocketMQ自带的事务机制来发送消息

①首先生产者发送half消息到RocketMQ中,此时消费者是无法消费half消息的,若half消息就发送失败了,则执行相应的回滚逻辑
②half消息发送成功之后,且RocketMQ返回成功响应,则执行生产者的核心链路
③如果生产者自己的核心链路执行失败,则回滚,并通知RocketMQ删除half消息
④如果生产者的核心链路执行成功,则通知RocketMQ commit half消息,让消费者可以消费这条数据 

场景二: 异步刷盘策略改为同步刷盘,并采用主从架构

① 将os cache的异步刷盘策略改为同步刷盘,一旦同步刷盘返回成功,那么就一定保证消息已经持久化到磁盘中了;
②为了保证磁盘损坏不会丢失数据,对RocketMQ采用主从机构,集群部署,Leader中的数据在多个Follower中都存有备份,防止单点故障。

场景三: 消息到达了消费者,RocketMQ在代码中就能保证消息不会丢失

①RocketMQ在消费者中注册了一个监听器,当消费者获取到了消息,就会去回调这个监听器函数,去处理里面的消息,当消息处理完毕,才会返回CONSUME_SUCCESS
②只有返回了CONSUME_SUCCESS,消费者才会告诉RocketMQ我已经消费完了,此时如果消费者宕机,消息已经处理完了,也就不会丢失消息了
③如果消费者还没有返回CONSUME_SUCCESS时就宕机了,那么RocketMQ就会认为你这个消费者节点挂掉了,会自动故障转移,将消息交给消费者组的其他消费者去消费这个消息,保证消息不会丢失 
//注册消息监听器处理消息
consumer.registerMessageListener(new MessageListenerConcurrently() {
   @Override
    public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context){                                                          
        //对消息进行处理
        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
    }
});

消息零丢失带来性能和吞吐的下降

① 使用事务机制传输消息,会比普通的消息传输多出很多步骤,耗费性能

② 同步刷盘相比异步刷盘,一个是存储在磁盘中,一个存储在内存中,速度完全不是一个数量级

③主从架构的话,需要Leader将数据同步给Follower,消费时无法异步消费,只能等待消费完成再通知RocketMQ消费完成 
 
原文链接:https://blog.csdn.net/LO_YUN/article/details/103949317
posted @   白玉神驹  阅读(384)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
历史上的今天:
2019-07-18 项目的容器化部署
2019-07-18 Docker-部署数据库
2019-07-18 用select2设置指定值为选中状态并显示
2019-07-18 Docker中修改Tomcat端口号
2019-07-18 Docker数据卷
点击右上角即可分享
微信分享提示