全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-22 8 分钟 ✍️ juanwangdev

镜像队列配置

镜像队列通过将队列内容复制到集群中的多个节点,确保单个节点故障时消息不丢失,消费者可继续从新的Master节点消费。

定义

镜像队列基于Policy机制配置,通过ha-mode参数指定镜像模式(all/exactly/nodes),使队列在多个节点间同步复制消息和消费者状态。

Maven依赖

XML
<dependency>
    <groupId>com.rabbitmq</groupId>
    <artifactId>amqp-client</artifactId>
    <version>5.20.0</version>
</dependency>

配置方式

通过rabbitmqctl配置

Bash
# 模式一:镜像到所有节点
rabbitmqctl set_policy ha-all "^ha\." '{"ha-mode":"all"}' --apply-to queues

# 模式二:镜像到指定数量节点
rabbitmqctl set_policy ha-two "^orders\." '{"ha-mode":"exactly","ha-params":2}' --apply-to queues

# 模式三:镜像到特定节点
rabbitmqctl set_policy ha-nodes "^logs\." '{"ha-mode":"nodes","ha-params":["rabbit@node-b","rabbit@node-c"]}' --apply-to queues

# 设置同步模式(默认为automatic)
rabbitmqctl set_policy ha-sync "^sync-queue\." '{"ha-mode":"all","ha-sync-mode":"manual"}' --apply-to queues

Policy参数说明

参数说明
ha-mode镜像模式:all(全部节点)、exactly(指定数量)、nodes(指定节点)
ha-params配合exactly时为节点数量;配合nodes时为节点名称数组
ha-sync-mode同步模式:automatic(自动)、manual(手动)。自动模式下新Slave立即同步,可能影响写入性能
ha-promote-on-shutdownMaster关闭时是否提升Slave:when-correctly-synced(仅已同步时提升)、always(总是提升)

Java代码声明队列

Java
import com.rabbitmq.client.*;

import java.util.HashMap;
import java.util.Map;

public class MirroredQueueExample {
    private static final String QUEUE_NAME = "ha.orders";
    private static final String EXCHANGE_NAME = "orders_exchange";

    public static void main(String[] args) throws Exception {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        factory.setPort(5672);
        factory.setUsername("guest");
        factory.setPassword("guest");

        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();

        // 声明交换机
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT, true);

        // 声明持久化队列(镜像由Policy控制,此处无需特殊参数)
        Map<String, Object> queueArgs = new HashMap<>();
        channel.queueDeclare(QUEUE_NAME, true, false, false, queueArgs);

        // 绑定队列到交换机
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "orders");

        // 发布持久化消息
        String message = "order-998877";
        channel.basicPublish(EXCHANGE_NAME, "orders",
            MessageProperties.PERSISTENT_TEXT_PLAIN,
            message.getBytes("UTF-8"));
        System.out.println("发送: " + message);

        // 消费消息
        DeliverCallback deliverCallback = (consumerTag, delivery) -> {
            String msg = new String(delivery.getBody(), "UTF-8");
            System.out.println("收到: " + msg);
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
        };

        channel.basicConsume(QUEUE_NAME, false, deliverCallback, consumerTag -> {});
    }
}

镜像队列运行逻辑

text
Master节点: 处理所有读写请求
    │
    ├──▶ 写入消息
    │       │
    │       ├──▶ 本地存储
    │       │
    │       └──▶ 同步到所有Slave
    │               │
    │               ├──▶ Node-B Slave
    │               │
    │               └──▶ Node-C Slave
    │
    └──▶ 消费者消费(仅Master处理)
  • 所有读写操作由Master处理,Slave仅接收同步数据
  • 消费者连接到Master,消费后Master将ACK同步到Slave
  • Master宕机时,最老的Slave提升为新的Master

ha-sync-mode=manual时,新加入的Slave不会自动同步已有消息,需管理员手动触发同步。适合大规模集群,避免同步流量冲击网络。

注意事项

  1. 性能损耗:每次写入需复制到所有镜像节点,写入延迟随节点数线性增长。

  2. 脑裂风险:网络分区时,若多个节点均认为自己是Master,可能导致数据不一致。使用pause_minority策略可缓解。

  3. 同步模式选择automatic保证新Slave立即同步,适合小规模集群;manual适合大规模集群,需手动触发初始同步。

  4. 与Quorum Queue互斥:同一队列不能同时使用镜像和仲裁模式,需选择其中一种。

  5. Policy优先级:多个Policy匹配时,优先级按Priority参数决定,数值大的优先。

要点总结

  • 镜像队列通过Policy的ha-mode参数配置,支持all、exactly、nodes三种模式
  • 所有读写操作由Master处理,Slave仅接收同步数据
  • Master宕机时最老Slave自动接管,保障队列持续可用
  • ha-sync-mode控制新Slave同步方式,automatic立即同步,manual需手动触发
  • 镜像复制增加写入延迟,节点越多性能损耗越大

📝 发现内容有误?点击此处直接编辑

← 上一篇 负载均衡配置
下一篇 → 集群加入与离开
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库