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 次。

相关推荐
我命由我123453 分钟前
Java 开发问题:包名 ‘com.my.compressimagetest‘ 与同名的类发生冲突
java·开发语言·学习·java-ee·intellij-idea·学习方法·intellij idea
⑩-9 分钟前
Sleep与Wait的区别
java·开发语言
程序员阿鹏9 分钟前
List和Set的区别
java·开发语言·数据结构·后端·list
CHANG_THE_WORLD10 分钟前
6.2.在汇编层面,数据本身没有类型
java·服务器·汇编
郑州光合科技余经理12 分钟前
技术解析:如何打造适应多国市场的海外跑腿平台
java·开发语言·javascript·mysql·spring cloud·uni-app·php
IT 行者13 分钟前
SpringBoot版本升级插件:用OpenRewrite 轻松升级 Spring Boot 2 到 4
java·spring boot·后端
lkbhua莱克瓦2428 分钟前
多线程综合练习3
java·开发语言·多线程·githup
步步为营DotNet41 分钟前
深度解析.NET中属性(Property)的幕后机制:优化数据访问与封装
java·算法·.net
Swift社区42 分钟前
LeetCode 454 - 四数相加 II
java·算法·leetcode
想做后端的小C43 分钟前
Java:访问权限
java·开发语言