RocketMQ 如何保证消息不丢失?

RocketMQ 的消息想要确保不丢失,需要生产者、消费者以及 Broker 的共同努力,缺一不可。

生产者(Producer)

1、发送方式:选择同步发送

  • 同步发送:发送消息后,需要阻塞等待 Broker 确认收到消息,生产者才能拿到返回的 SendResult
  • 异步发送:Producer 首先构建一个向 broker 发送消息的任务,把该任务提交给线程池,等执行完该任务时,回调用户自定义的回调函数,执行处理结果。

2、重试机制

生产者因为网络故障、服务异常等原因导致调用, RocketMQ 内置请求重试逻辑,默认重试 3 次。

重试 3 次意思是一共会发 4 次消息,1 次原始消息,3 次重试消息。

Broker

1、刷盘策略:选择同步刷盘

  • 同步刷盘:如果想要保证消息不丢失,可以将消息保存机制修改为同步刷盘,这样,Broker会在同步请求中把数据保存在磁盘上,确保保存成功后再返回确认结果给生产者。
  • 异步刷盘:异步发送的话就需要生产者重写 SendCalback 的 onSuccess 和 onException 方法,用于给 Broker 进行回调。在方法中实现消息的确认或者重新发送。
java 复制代码
# 默认情况为 ASYNC_FLUSH
flushDiskType = SYNC_FLUSH

2、同步机制:同步复制

为了保证消息不丢失,RocketMQ肯定要通过集群方式进行部署,Broker 通常采用一主多从部署方式,并且采用主从同步的方式做数据复制

默认方式下,Broker 在接收消息后,写入 master 成功,就可以返回确认响应给生产者了,接着消息将会异步复制到 slave 节点。但是如果这个过程中,Master 的磁盘损坏了。那就会导致数据丢失了。

如果想要解决这个问题,可以配置同步复制的方式,即 Master 在将数据同步到 Slave 节点后,再返回给生产者确认结果。

java 复制代码
# 默认为 ASYNC_MASTER
brokerRole = SYNC_MASTER

消费者(Consumer

1、At least Once 机制(先业务后ack)

At least Once:
Consumer 先 pull【主动拉取Broker中的信息】 消息到本地,消费完成后,才向服务器返回 ack。

通常消费消息的 ack 机制一般分为两种思路:

  • 第一种:先提交后消费;
  • 第二种:先消费,消费成功后再提交【这个更稳当】

思路一可以解决重复消费的问题但是会丢失消息,因此 Rocketmq 默认实现的是思路二,由各自 consumer 业务方保证幂等来解决重复消费问题。

幂等:通过给每个消息携带一个唯一标识信息,去数据库进行判断。或者在 producer 的时候就存储一个唯一标识(消息),消费成功删除redis中的消息确保不被重复消费

简单来说就是,在消费者的代码中,一定要在业务逻辑的最后一步returnConsumeConcurrentlyStatuS.CONSUME SUCCESS;
当然,也可以先把数据保存在数据库中,就返回,然后自己再慢慢处理。

2、消费消息重试机制

在消费者端,需要确保在消息拉取并消费成功之后再给 Broker 返回 ACK,就可以保证消息不丢失了,如果这个过程中 Broker 一直没收到 ACK,那么就可以重试。默认 16 次。

相关推荐
小Ti客栈17 小时前
Spring Boot 集成 Springdoc-OpenAPI 与 Knife4j实现接口文档与可视化调试
java·spring boot·后端
Ai拆代码的曹操17 小时前
Spring 事务 REQUIRES_NEW 嵌套调用:连接池翻倍的秘密
java·后端·spring
动恰客流统计18 小时前
ReID边缘计算视觉统计:餐饮店客流增长的数字化破局路径
java·大数据·运维·人工智能
Ivanqhz18 小时前
Rust &‘static str浅析
java·前端·javascript·rust
weixin_4196583121 小时前
Docker 搭建 Jenkins 服务
java·docker·jenkins
captain3761 天前
多线程线程安全问题
java·java-ee
CoderYanger1 天前
A.每日一题:1979. 找出数组的最大公约数
java·程序人生·算法·leetcode·面试·职场和发展·学习方法
灵极海1 天前
LangChain4j RAG 实战完整指南:从入门到踩坑
java·langchain
yaoxin5211231 天前
476. Java 反射 - 调用方法
java·开发语言
Ivanqhz1 天前
Rust Lazy浅析
java·javascript·rust