集群搭建

RabbitMQ 集群可以提高系统的可用性和吞吐量。

🎯 本章目标

  • 理解 RabbitMQ 集群原理
  • 掌握集群搭建方法
  • 了解集群节点管理

📦 集群架构

集群特点

特点说明
元数据同步所有节点共享队列、交换机等元数据
队列数据默认只存在于声明它的节点
负载均衡客户端可以连接任意节点
故障转移节点故障时,连接自动切换

节点类型

类型说明特点
磁盘节点元数据存储在磁盘数据持久化
内存节点元数据存储在内存性能更高

注意

集群中至少需要一个磁盘节点来保存元数据。

🐳 Docker Compose 搭建

docker-compose.yml

version: '3.8'

services:
  rabbitmq1:
    image: rabbitmq:3.12-management
    hostname: rabbitmq1
    container_name: rabbitmq1
    ports:
      - "5672:5672"
      - "15672:15672"
    environment:
      - RABBITMQ_ERLANG_COOKIE=secret_cookie_here
      - RABBITMQ_DEFAULT_USER=admin
      - RABBITMQ_DEFAULT_PASS=admin123
      - RABBITMQ_NODENAME=rabbit@rabbitmq1
    volumes:
      - rabbitmq1_data:/var/lib/rabbitmq
    networks:
      - rabbitmq_cluster

  rabbitmq2:
    image: rabbitmq:3.12-management
    hostname: rabbitmq2
    container_name: rabbitmq2
    ports:
      - "5673:5672"
      - "15673:15672"
    environment:
      - RABBITMQ_ERLANG_COOKIE=secret_cookie_here
      - RABBITMQ_DEFAULT_USER=admin
      - RABBITMQ_DEFAULT_PASS=admin123
      - RABBITMQ_NODENAME=rabbit@rabbitmq2
    volumes:
      - rabbitmq2_data:/var/lib/rabbitmq
    depends_on:
      - rabbitmq1
    networks:
      - rabbitmq_cluster

  rabbitmq3:
    image: rabbitmq:3.12-management
    hostname: rabbitmq3
    container_name: rabbitmq3
    ports:
      - "5674:5672"
      - "15674:15672"
    environment:
      - RABBITMQ_ERLANG_COOKIE=secret_cookie_here
      - RABBITMQ_DEFAULT_USER=admin
      - RABBITMQ_DEFAULT_PASS=admin123
      - RABBITMQ_NODENAME=rabbit@rabbitmq3
    volumes:
      - rabbitmq3_data:/var/lib/rabbitmq
    depends_on:
      - rabbitmq1
    networks:
      - rabbitmq_cluster

volumes:
  rabbitmq1_data:
  rabbitmq2_data:
  rabbitmq3_data:

networks:
  rabbitmq_cluster:
    driver: bridge

启动并加入集群

# 启动所有节点
docker-compose up -d

# 等待节点启动
sleep 30

# 节点2加入集群
docker exec rabbitmq2 rabbitmqctl stop_app
docker exec rabbitmq2 rabbitmqctl reset
docker exec rabbitmq2 rabbitmqctl join_cluster rabbit@rabbitmq1
docker exec rabbitmq2 rabbitmqctl start_app

# 节点3加入集群
docker exec rabbitmq3 rabbitmqctl stop_app
docker exec rabbitmq3 rabbitmqctl reset
docker exec rabbitmq3 rabbitmqctl join_cluster rabbit@rabbitmq1
docker exec rabbitmq3 rabbitmqctl start_app

# 查看集群状态
docker exec rabbitmq1 rabbitmqctl cluster_status

🖥️ 手动搭建(Linux)

1. 准备工作

在三台服务器上安装 RabbitMQ:

节点主机名IP
节点1rabbitmq1192.168.1.101
节点2rabbitmq2192.168.1.102
节点3rabbitmq3192.168.1.103

2. 配置 hosts

在每台服务器的 /etc/hosts 中添加:

192.168.1.101 rabbitmq1
192.168.1.102 rabbitmq2
192.168.1.103 rabbitmq3
# 在 rabbitmq1 上查看 cookie
cat /var/lib/rabbitmq/.erlang.cookie

# 复制到其他节点
scp /var/lib/rabbitmq/.erlang.cookie root@rabbitmq2:/var/lib/rabbitmq/
scp /var/lib/rabbitmq/.erlang.cookie root@rabbitmq3:/var/lib/rabbitmq/

# 确保权限正确
chmod 400 /var/lib/rabbitmq/.erlang.cookie
chown rabbitmq:rabbitmq /var/lib/rabbitmq/.erlang.cookie

4. 加入集群

在 rabbitmq2 和 rabbitmq3 上执行:

# 停止应用
rabbitmqctl stop_app

# 重置节点
rabbitmqctl reset

# 加入集群
rabbitmqctl join_cluster rabbit@rabbitmq1

# 启动应用
rabbitmqctl start_app

5. 验证集群

rabbitmqctl cluster_status

输出示例:

Cluster status of node rabbit@rabbitmq1 ...
Basics

Cluster name: rabbit@rabbitmq1
Total CPU cores available cluster-wide: 12

Disk Nodes

rabbit@rabbitmq1
rabbit@rabbitmq2
rabbit@rabbitmq3

Running Nodes

rabbit@rabbitmq1
rabbit@rabbitmq2
rabbit@rabbitmq3

🔧 集群管理命令

节点管理

# 查看集群状态
rabbitmqctl cluster_status

# 将节点改为内存节点
rabbitmqctl change_cluster_node_type ram

# 将节点改为磁盘节点
rabbitmqctl change_cluster_node_type disc

# 移除节点
rabbitmqctl forget_cluster_node rabbit@rabbitmq3

# 重命名节点
rabbitmqctl rename_cluster_node oldname newname

节点维护

# 停止应用(不退出 Erlang)
rabbitmqctl stop_app

# 启动应用
rabbitmqctl start_app

# 重置节点(清除所有数据)
rabbitmqctl reset

# 强制重置(即使无法连接集群)
rabbitmqctl force_reset

💻 Java 连接集群

@Configuration
public class RabbitMQClusterConfig {
    
    @Bean
    public ConnectionFactory connectionFactory() {
        CachingConnectionFactory factory = new CachingConnectionFactory();
        
        // 设置集群地址
        factory.setAddresses("192.168.1.101:5672,192.168.1.102:5672,192.168.1.103:5672");
        factory.setUsername("admin");
        factory.setPassword("admin123");
        factory.setVirtualHost("/");
        
        // 连接重试
        factory.setConnectionTimeout(30000);
        
        return factory;
    }
}

或使用配置文件:

spring:
  rabbitmq:
    addresses: 192.168.1.101:5672,192.168.1.102:5672,192.168.1.103:5672
    username: admin
    password: admin123
    virtual-host: /
    connection-timeout: 30000

📝 本章小结

要点说明
Erlang Cookie集群节点必须使用相同的 Cookie
节点类型至少一个磁盘节点
元数据自动在节点间同步
队列数据默认不同步,需要配置镜像

下一步

集群搭建完成后,需要配置高可用来保证队列数据不丢失,请学习 高可用方案