Skip to content

第七部分:消息队列 MQ 高可用分布式、死信与最终一致性 ​


第 1 章:RocketMQ & Kafka 分布式高可用物理架构 ​

在高并发分布式系统中,消息队列 (MQ) 的高可用直接决定了系统的抗风险能力。

text
[ RocketMQ 高可用 ] ➔ NameServer 无状态集群 + Broker Master/Slave (SYNC_MASTER 双写 + SYNC_FLUSH 同步刷盘) + DLeger (Raft)
[ Kafka 高可用 ]    ➔ Controller 控制器 + Topic 多 Partition + ISR (In-Sync Replicas) 动态副本 + acks=-1 (all)

1.1 RocketMQ 分布式高可用与刷盘物理机制 ​

text
                                [ NameServer 集群 ]
                                (无状态, 互不通信, 节点全量心跳)
                                          │
                   ┌──────────────────────┴──────────────────────┐
                   ↓                                             ↓
       [ Broker Group 1 ]                            [ Broker Group 2 ]
 ┌──────────────────────────┐                  ┌──────────────────────────┐
 │ Master 1 (SYNC_MASTER)   │ ──(同步双写)──>  │ Master 2 (SYNC_MASTER)   │
 │ Slave 1 (ASYNC_FLUSH)    │                  │ Slave 2 (ASYNC_FLUSH)    │
 └──────────────────────────┘                  └──────────────────────────┘

💬 RocketMQ 生产环境绝对零丢失配置

  1. 刷盘策略 (FlushDiskType):
    • ASYNC_FLUSH (异步刷盘,默认):PageCache 攒批后批量刷盘,性能极高,但断电可能丢少量数据;
    • SYNC_FLUSH (同步刷盘):消息必须物理写入 OS 磁盘后才返回成功,保障数据不丢失。
  2. 复制策略 (BrokerRole):
    • SYNC_MASTER (同步双写):Master 收到消息后必须同步复制给至少 1 个 Slave,两者都写成功后才返回 Producer 成功;
  3. DLeger 自动选主 (基于 Raft 协议): 若开启 DLeger 组,当 Master 宕机后,多台 Broker 通过 DLeger 自动选举出新 Master,实现毫秒级无缝故障转移。

1.2 Kafka Partition 副本、ISR 机制与 ACK 三重物理含义 ​

text
[ Topic: order_topic ]
   └── [ Partition 0 ]
         ├── Leader 副本 (负责所有 Producer 写与 Consumer 读)
         ├── Follower 副本 1 (在 ISR 队列中,实时同步 ACK) ➔ [ ISR 列表: Leader, Follower 1 ]
         └── Follower 副本 2 (同步延迟 > 10秒,被剔除出 ISR) ➔ [ OSR 列表: Follower 2 ]

💬 Kafka acks 参数的三种物理含义与生产选型

Producer 配置 request.required.acks:

  1. acks=0 (极速无保障模式):
    • 机制:Producer 把消息发出去即代表成功,不等待 Leader 任何确认;
    • 风险:网络抖动或 Leader 崩溃,消息直接丢失;适合日志收集 (access_log);
  2. acks=1 (Leader 写入确认模式,默认):
    • 机制:Leader 副本成功写入物理日志后即返回成功;
    • 风险:若 Leader 刚写完还没来得及同步给 Follower 就崩溃,仍会丢数据;
  3. acks=-1 或 acks=all (最安全模式):
    • 机制:消息必须成功写入 ISR (In-Sync Replicas) 列表中的所有 Follower 副本 之后,才返回成功;
    • 最佳实践:必须搭配 min.insync.replicas=2 配置。即使 1 个 Leader 崩溃,ISR 中的 Follower 也会被 Controller 升为新 Leader,实现金融级绝对零丢失。

第 2 章:死信队列 (DLQ)、TTL+DLX 延迟队列与 100 万积压处理 ​

2.1 死信队列 (DLQ) 三大产生条件与多语言搭建 ​

text
[ Producer ] ➔ [ Normal Exchange / Queue ] ➔ (触发死信 3 条件) ➔ [ DLX (死信交换机) ] ➔ [ DLQ (死信队列) ] ➔ [ 人工干预 / 监控告警 ]

💬 死信产生的 3 大物理条件

  1. 消息被 Consumer 显式拒绝:执行 basic.reject(requeue=false) 或 basic.nack(requeue=false);
  2. 消息在 TTL (Time-To-Live) 生存时间到期后依然未被消费;
  3. 队列达到了最大物理长度限制 (x-max-length),新到消息被挤出队列。

2.2 延迟队列中 UNPAID 状态机强校验机制 ​

php
// 延迟消费 30 分钟未支付订单 - 消费端逻辑
public function handleDelayMessage(array $data) {
    $orderId = $data['order_id'];
    $order = Order::find($orderId);

    // 核心物理强校验:绝不能直接关单!
    if (!$order || $order->status !== 'UNPAID') {
        // 订单已支付或已取消,直接安全丢弃消息
        return true;
    }

    // 在本地事务中执行关单与退还库存
    Db::transaction(function() use ($order) {
        $order->status = 'CANCELLED';
        $order->save();
        Product::where('id', $order->product_id)->inc('stock', $order->num)->update();
    });
}

🔍 本章 6 重自审计报告 ​

  1. 【知识审计】:已全量补充 RocketMQ 刷盘策略 (同步/异步刷盘)、SYNC_MASTER 同步双写、DLeger Raft 选主,以及 Kafka Partition 副本、ISR 动态队列、acks (0/1/-1) 参数物理含义与 UNPAID 状态机强校验!已适配移动端 ::: info 💬 自适应排版!

Released under the MIT License.