手把手,Rabbitmq3.12,镜像队列如何配置,​​Spring Boot如何连接镜像队列集群

176 阅读2分钟

RabbitMQ镜像队列集群配置

前置要求

  • 至少3个RabbitMQ节点(推荐奇数个节点以实现高可用)
  • 所有节点时间同步
  • 节点间网络通畅(开放4369, 25672, 5672, 15672, 61613等端口)
  • 相同的Erlang cookie(位于/var/lib/rabbitmq/.erlang.cookie

集群配置步骤

  1. 安装RabbitMQ
    在所有节点上安装相同版本的RabbitMQ 3.12:

    # Ubuntu/Debian
    curl -fsSL https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc | sudo apt-key add -
    echo "deb https://dl.bintray.com/rabbitmq/debian $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/rabbitmq.list
    sudo apt-get update
    sudo apt-get install rabbitmq-server
    
    # 启动服务
    sudo systemctl enable rabbitmq-server
    sudo systemctl start rabbitmq-server
    

  2. 配置主机名解析
    确保所有节点可以相互解析主机名,编辑/etc/hosts

    192.168.1.10 rabbitmq-node1
    192.168.1.11 rabbitmq-node2
    192.168.1.12 rabbitmq-node3
    

  3. 同步Erlang cookie
    将其中一个节点的cookie复制到其他节点:

    # 在主节点上查看cookie
    sudo cat /var/lib/rabbitmq/.erlang.cookie
    
    # 在其他节点上更新cookie(确保RabbitMQ已停止)
    sudo systemctl stop rabbitmq-server
    sudo echo "YOUR_ERLANG_COOKIE" > /var/lib/rabbitmq/.erlang.cookie
    sudo chown rabbitmq:rabbitmq /var/lib/rabbitmq/.erlang.cookie
    sudo chmod 400 /var/lib/rabbitmq/.erlang.cookie
    

  4. 组建集群
    将节点加入集群:

    # 在节点2上执行
    sudo rabbitmqctl stop_app
    sudo rabbitmqctl join_cluster rabbit@rabbitmq-node1
    sudo rabbitmqctl start_app
    
    # 在节点3上执行
    sudo rabbitmqctl stop_app
    sudo rabbitmqctl join_cluster rabbit@rabbitmq-node1
    sudo rabbitmqctl start_app
    
    # 验证集群状态
    sudo rabbitmqctl cluster_status
    

镜像队列策略配置

  1. 设置镜像队列策略
    在所有队列上启用镜像,复制到所有节点:

    rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all","ha-sync-mode":"automatic"}'
    

或更保守的策略(推荐):

# 镜像到2个节点(包括主节点),自动同步
rabbitmqctl set_policy ha-two "^" '{"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"}'

# 或按节点名称镜像
rabbitmqctl set_policy ha-nodes "^" '{"ha-mode":"nodes","ha-params":["rabbit@node1","rabbit@node2"]}'

  1. 启用管理插件(可选)
    如果需要Web管理界面:

    sudo rabbitmq-plugins enable rabbitmq_management
    

Spring Boot连接镜像队列集群

添加依赖

pom.xml中添加AMQP依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

配置连接

application.yml中配置集群连接:

spring:
  rabbitmq:
    addresses: rabbitmq-node1:5672,rabbitmq-node2:5672,rabbitmq-node3:5672
    username: your_username
    password: your_password
    virtual-host: /
    # 连接重试配置
    connection-timeout: 10000
    template:
      retry:
        enabled: true
        initial-interval: 1000
        max-attempts: 3
        multiplier: 1.5
    listener:
      simple:
        retry:
          enabled: true
          max-attempts: 3
          initial-interval: 1000
        acknowledge-mode: auto
        # 集群环境下建议开启消费者重试
        default-requeue-rejected: false

代码示例

  1. 配置类

    @Configuration
    public class RabbitMQConfig {
    
        @Value("${spring.rabbitmq.addresses}")
        private String addresses;
        
        @Value("${spring.rabbitmq.username}")
        private String username;
        
        @Value("${spring.rabbitmq.password}")
        private String password;
    
        @Bean
        public CachingConnectionFactory connectionFactory() {
            CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
            connectionFactory.setAddresses(addresses);
            connectionFactory.setUsername(username);
            connectionFactory.setPassword(password);
            // 开启连接失败重试
            connectionFactory.setConnectionTimeout(10000);
            return connectionFactory;
        }
    
        @Bean
        public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
            RabbitTemplate template = new RabbitTemplate(connectionFactory);
            template.setMessageConverter(jsonMessageConverter());
            // 开启发送确认
            template.setConfirmCallback((correlationData, ack, cause) -> {
                if (!ack) {
                    System.out.println("消息发送失败: " + cause);
                }
            });
            // 开启返回模式
            template.setReturnsCallback(returned -> {
                System.out.println("消息被退回: " + returned);
            });
            template.setMandatory(true);
            return template;
        }
    
        @Bean
        public MessageConverter jsonMessageConverter() {
            return new Jackson2JsonMessageConverter();
        }
    }
    

  2. 生产者示例

    @Component
    public class MessageProducer {
        
        @Autowired
        private RabbitTemplate rabbitTemplate;
        
        public void sendMessage(String exchange, String routingKey, Object message) {
            rabbitTemplate.convertAndSend(exchange, routingKey, message, 
                new CorrelationData(UUID.randomUUID().toString()));
        }
    }
    

  3. 消费者示例

    @Component
    public class MessageConsumer {
        
        @RabbitListener(queues = "your.queue.name")
        public void handleMessage(YourMessageClass message, Channel channel, 
                                @Header(AmqpHeaders.DELIVERY_TAG) long tag) {
            try {
                // 处理消息
                processMessage(message);
                // 确认消息
                channel.basicAck(tag, false);
            } catch (Exception e) {
                // 处理失败,拒绝消息(可配置重试策略)
                channel.basicNack(tag, false, true);
            }
        }
        
        private void processMessage(YourMessageClass message) {
            // 业务逻辑处理
        }
    }
    

验证与测试

  1. 集群状态验证

    # 检查集群状态
    rabbitmqctl cluster_status
    
    # 检查策略
    rabbitmqctl list_policies
    

  2. Spring Boot应用测试
    创建测试类验证连接和消息发送:

    @SpringBootTest
    public class RabbitMQTest {
        
        @Autowired
        private MessageProducer producer;
        
        @Test
        public void testSendMessage() {
            producer.sendMessage("exchange.test", "routing.key", "Test Message");
            // 添加断言验证消息发送成功
        }
    }
    

    常见问题排查

  3. 节点无法加入集群

    • 检查防火墙设置
    • 验证Erlang cookie是否一致
    • 确认主机名解析正确
  4. 镜像队列同步失败

    • 检查网络连接
    • 确认磁盘空间充足
    • 验证RabbitMQ版本一致性
  5. Spring Boot连接失败

    • 检查配置的地址和端口
    • 验证用户名和密码
    • 确认虚拟主机存在
  6. 消息丢失问题

    • 启用发布者确认
    • 配置持久化队列和消息
    • 实现消费者确认机制
  7. 性能问题

    • 适当调整线程池大小
    • 考虑使用批量消息处理
    • 监控系统资源使用情况

通过以上配置和代码示例,我们应该能够成功搭建RabbitMQ镜像队列集群,并在Spring Boot应用中连接和使用该集群。记得根据实际生产环境调整配置参数,并进行充分的测试。