RocketMQ - 从消息可靠传输谈高可用

news2025/4/1 23:24:53

先稍微介绍下RocketMQ架构。

在这里插入图片描述

主从架构
  • Broker 集群:每个 Broker 分为 MasterSlave 角色,Master 负责读写,Slave 作为热备。

    • 同步复制(SYNC_MASTER):消息写入 Master 后,需等待 Slave 同步完成才返回成功,保证数据强一致(牺牲部分性能)。

    • 异步复制(ASYNC_MASTER):消息写入 Master 后立即返回成功,Slave 异步复制,性能更高但可能丢失少量数据。

  • 故障自动切换

    • 基于 Dledger(Raft 协议实现):在 RocketMQ 4.5+ 版本中,Dledger 实现自动选主,当 Master 宕机时,Slave 自动晋升为新 Master,避免单点故障。

    • 旧版本通过 HA(High Availability) 服务手动切换。

NameServer 高可用
  • NameServer 无状态集群:NameServer 作为轻量级服务发现组件,多个节点互相独立,无数据同步依赖,通过客户端轮询访问不同节点实现容灾。

    • NameServer 节点间的路由信息可能存在短暂不一致(如某个 NameServer 尚未收到 Broker 的最新心跳),但通过以下机制保证最终一致:

      • Broker 向所有 NameServer 周期性上报心跳,存活节点最终会同步最新状态。

      • 客户端定时拉取路由表,覆盖旧缓存。

  • 客户端缓存路由信息:Producer 和 Consumer 会缓存 Topic 的路由信息,即使 NameServer 短暂不可用,仍能继续收发消息。

消息可靠传输

从消息可靠传输可以看到很多RocketMQ高可用的设计。

生产端

使用Dledger集群方案

在这里插入图片描述

DLedger是一套基于Raft协议的分布式日志存储组件,在使用Dledger技术搭建的RocketMQ集群中,Dledger会通过两阶段提交的方式保证文件在主从之间成功同步。

配置同步刷盘

SYNC_FLUSH(同步刷新)相比于ASYNC_FLUSH(异步处理)会损失很多性能,但是也更可靠,所以需要根据实际的业务场景做好权衡。

使用事务消息

基于Apache RocketMQ实现的分布式事务消息功能,在普通消息基础上,支持二阶段的提交能力。将二阶段提交和本地事务绑定,实现全局提交结果的一致性。

观察回执状态

对于消费可靠传输,先关注下生产端的回执状态,RocketMQ 的同步发送(syncSend)和异步发送(asyncSend)均会返回以下状态(通过 SendStatus 枚举类定义):

SEND_OK
  • 含义:消息发送成功,且满足 Broker 的持久化策略。

  • 触发条件

    • 消息已成功写入 Broker 的 CommitLog。

    • 若 Broker 配置为 SYNC_MASTER(同步复制),需主节点和从节点均刷盘完成。

    • 若配置为 ASYNC_MASTER(异步复制),只需主节点刷盘完成。

  • 处理建议

    • 业务可认为消息已可靠存储,无需重试。

    • 需注意:SEND_OK 仅表示 Broker 接收成功,不保证消费者一定能消费到(例如网络故障导致未推送)。

FLUSH_DISK_TIMEOUT
  • 含义:Broker 刷盘超时。

  • 触发条件

    • Broker 的刷盘策略为 SYNC_FLUSH(同步刷盘)时,等待刷盘超时(默认5秒)。

    • 磁盘 I/O 压力大或故障导致无法及时刷盘。

  • 处理建议

    • 消息可能未持久化到磁盘,存在丢失风险。

    • 需重试发送,并监控 Broker 磁盘状态。

FLUSH_SLAVE_TIMEOUT
  • 含义:主节点同步到从节点(Slave)超时。

  • 触发条件

    • Broker 角色为 SYNC_MASTER(同步复制)。

    • 主节点等待 Slave 同步确认超时(默认5秒)。

  • 处理建议

    • 消息在主节点已持久化,但未同步到 Slave。

    • 需重试发送,避免主节点宕机后数据丢失。

SLAVE_NOT_AVAILABLE
  • 含义:从节点(Slave)不可用。

  • 触发条件

    • Broker 角色为 SYNC_MASTER,但当前无可用 Slave。

    • Slave 节点宕机或网络隔离。

  • 处理建议

    • 主节点已接收消息,但无法保证高可用。

    • 需检查 Slave 状态,必要时修复集群。

Keys的使用

每个消息在业务层面一般建议映射到业务的唯一标识并设置到keys字段,方便将来定位消息丢失问题。服务器会为每个消息创建索引(哈希索引),应用可以通过topic、key来查询这条消息内容,以及消息被谁消费。由于是哈希索引,请务必保证key尽可能唯一,这样可以避免潜在的哈希冲突。常见的设置策略使用订单Id、用户Id、请求Id等比较离散的唯一标识来处理。

消费端

不要使用异步消费

正常情况下,消费者端都是需要先处理本地事务,然后再给MQ一个ACK响应,这时MQ就会修改Offset,将消息标记为已消费,从而不再往其他消费者推送消息。所以在Broker的这种重新推送机制下,消息是不会在传输过程中丢失的。但是也会有下面这种情况会造成服务端消息丢失:

 DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("please_rename_unique_group_name_4");
        consumer.registerMessageListener(new MessageListenerConcurrently() {
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
                                                            ConsumeConcurrentlyContext context) {
                new Thread(){
                    public void run(){
                        //处理业务逻辑
                        System.out.printf("%s Receive New Messages: %s %n", Thread.currentThread().getName(), msgs);
                    }
                };
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });

这种异步消费的方式,就有可能造成消息状态返回后消费者本地业务逻辑处理失败造成消息丢失的可能。

RocketMQ不可用降级方案

在这种情况下,RocketMQ相当于整个服务都不可用了,那他本身肯定无法给我们保证消息不丢失了。我们只能自己设计一个降级方案来处理这个问题了。例如在订单系统中,如果多次尝试发送RocketMQ不成功,那就只能另外找给地方,比如本地事务表,把订单消息缓存下来,然后起一个线程定时的扫描这些失败的订单消息,尝试往RocketMQ发送。这样等RocketMQ的服务恢复过来后,就能第一时间把这些消息重新发送出去。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2325212.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ES拼音分词自动补全实现

#测试拼音分词 POST /_analyze { "text":"如家酒店真不错", "analyzer": "pinyin" } #这里把拼音的首字母放到这里&#xff0c;也说明了这句话没有被分词&#xff0c;而是作为一个整体出现的 #还把每一个字都形成了一个拼音&#…

EFISH-SBC-RK3576 + 5G模组:无线工业相机与分布式AI质检‌

在智能制造与仓储物流场景中&#xff0c;传统有线工业相机存在部署成本高、灵活性差等痛点。‌eFish-SBC-RK3576‌ 通过 ‌5G无线传输 分布式NPU协同‌&#xff0c;实现跨产线、跨工厂的AI质检系统&#xff0c;检测效率提升300%&#xff0c;布线复杂度降低90%。 ‌1. 系统架构…

C/C++ 基础 - 回调函数

目录 前言 回调函数预备知识 函数指针 什么是函数指针 函数指针的语法 如何用函数指针调用函数 函数指针作为函数的参数 函数指针作为函数返回类型 函数指针数组 回调函数 什么是回调函数 为什么要用回调函数 怎么使用回调函数 总结 前言 在写项目的时候&#x…

【 <二> 丹方改良:Spring 时代的 JavaWeb】之 Spring Boot 中的消息队列:使用 RabbitMQ 实现异步处

<前文回顾> 点击此处查看 合集 https://blog.csdn.net/foyodesigner/category_12907601.html?fromshareblogcolumn&sharetypeblogcolumn&sharerId12907601&sharereferPC&sharesourceFoyoDesigner&sharefromfrom_link <今日更新> 一、开篇整…

DeepSeek分析仿写选题应该怎么做?

目录 选题分析&#xff1a;AIGC在学术写作中的应用及其与作者背景的关系 1. 选题背景与意义 2. 研究问题 3. 研究方法 4. 主要发现 5. 研究贡献 6. 研究局限与未来方向 7. 结论 8. 未来研究方向 大家好这里是AIWritePaper官方账号&#xff0c;官网&#x1f449;AIWrit…

19840 Dijkstra求最短路2

19840 Dijkstra求最短路2 相较于1&#xff0c;数据增强了&#xff0c;要用堆来优化&#xff0c;也就是优先队列。 ⭐️难度&#xff1a;中等 &#x1f31f;考点&#xff1a;Dijkstra、最短路问题 &#x1f4d6; &#x1f4da; import java.util.*;public class Main {static…

Redis-08.Redis常用命令-有序集合操作命令

一.有序集合操作命令 ZADD key score 1 member1 [score2 member2]&#xff1a; zadd zset 10.0 a 10.5 b ZRANGE key start stop [WITHSCORES]: zrange zset 0 -1 为何顺序为a&#xff0c;c&#xff0c;b&#xff1f; 因为 zrange zset 0 -1 withscores zrange key start …

LLaMA-Factory使用实战

LLaMA-Factory使用实战 项目介绍 项目地址&#xff1a;https://github.com/hiyouga/LLaMA-Factory 中文文档&#xff1a;安装 - LLaMA Factory 快速开始文档&#xff1a;https://zhuanlan.zhihu.com/p/695287607&#xff08;推荐参考&#xff09; 远程服务器通过本地代理加…

读一本书,骑行万里路:与维乐 Angel Rise+骑行看世界

最近读到了一本名为《自行车改变的世界&#xff1a;女性骑行的历史》的书&#xff0c;才发现原来女性的骑行自由来得并不轻易&#xff0c;激励着每一位女性勇敢地踏上骑行之路。而我一直在使用的维乐坐垫品牌&#xff0c;除了产品专业之外&#xff0c;也一直都非常关注女性骑行…

【大模型】SpringBoot整合LangChain4j实现RAG检索实战详解

目录 一、前言 二、LangChain4j 介绍 2.1 什么是LangChain4j 2.2 LangChain4j 主要特点 2.3 Langchain4j 核心组件 三、RAG介绍 3.1 什么是RAG 3.2 RAG工作流程 3.2.1 补充说明 3.3 Embedding模型 3.3.1 RAG实际使用步骤 3.3.2 什么是Embedding 3.3.3 Embedding 技…

流动的梦境:GPT-4o 的自回归图像生成深度解析

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

北大人工智能研究院朱松纯:“中国的AI叙事” 存在认知偏差

3月29日&#xff0c;在2025中关村论坛通用人工智能论坛上&#xff0c;北京通用人工智能学院院长&#xff0c;北京大学人工智能研究院、智能学院院长朱松纯表示&#xff0c;目前&#xff0c;行业对AI的讨论几乎被大模型能力所占据&#xff0c;而基础学科、原始创新与智能本质的研…

习题1.26

解释题&#xff0c;说简单也简单&#xff0c;难在如何表达清楚。 首先解释下代码的变化 (defn expmod[base exp m](cond ( exp 0) 1(even? exp) (mod (square (expmod base (/ exp 2) m)) m):else (mod (* base (expmod base (- exp 1) m)) m)))(defn expmod[base exp m](co…

FPGA调试笔记

XILINX SSTL属性电平报错 错误如下&#xff1a; [DRC BIVRU-1] Bank IO standard Vref utilization: Bank 33 contains ports that use a reference voltage. In order to use such standards in a bank that is not configured to use INTERNAL_VREF, the banks VREF pin mu…

基于Java(SSM)+Mysql实现移动大厅业务办理(增删改查)

基于 SSM 框架的移动业务大厅 数据库需要自行创建&#xff01; 一、 整体基本实现情况 对本学期的 Java 作业 1 的 SOSO 移动大厅进行改进&#xff0c; 基于 SSM、JSP、Maven、Tomcat、MySQL 等实现。 二、 实现详情 1、 工程结构图 2、 工程结构各部分实现 &#xff08;…

【字符设备驱动开发–IMX6ULL】(一)简介

【字符设备驱动开发–IMX6ULL】&#xff08;一&#xff09;简介 一、Linux驱动与裸机开发区别 1.裸机驱动开发回顾 ​ 1、底层&#xff0c;跟寄存器打交道&#xff0c;有些MCU提供了库。 spi.c&#xff1a;主机驱动&#xff08;换成任何一个设备之后只需要调用此文件里面的…

C++_STL之list篇

一、list的介绍 std::list是C标准模板库(STL)中的一个双向链表容器。与vector和deque不同&#xff0c;list不支持随机访问&#xff0c;但它在任何位置插入和删除元素都非常高效。 1.基本特性 (1)双向链表结构&#xff1a;每个元素都包含指向前驱和后继的指针 (2)非连续存储&…

Spring 声明式事务 万字详解(通俗易懂)

目录 Δ前言 一、声明式事务快速入门 1.为什么需要声明式事务&#xff1f; 2.定义&#xff1a; 3.应用实例&#xff1a; 二、声明式事务的传播机制 1.引出问题&#xff1a; 2.传播机制分类&#xff1a; 3.应用实例&#xff1a; 三、声明式事务的隔离机制 1.四种隔离级别&…

MySQL 当中的锁

MySQL 当中的锁 文章目录 MySQL 当中的锁MySQL 中有哪些主要类型的锁&#xff1f;请简要说明MySQL 的全局锁有什么用&#xff1f;MySQL 的表级锁有哪些&#xff1f;作用是什么&#xff1f;元数据锁&#xff08;MetaData Lock&#xff0c;MDL&#xff09;意向锁&#xff08;Inte…

[Linux]基础IO

基础IO C文件IO相关操作磁盘文件与内存文件inode&#xff08;index node&#xff09;硬链接与软连接硬链接软连接总结 动静态库静态库动态库总结 C文件IO相关操作 当前路径&#xff1a;进程运行的时候&#xff0c;所处的路径叫做当前路径 打开文件的时候&#xff0c;一定是进…