RabbitMQ镜像队列集群配置
前置要求
-
至少3个RabbitMQ节点(推荐奇数个节点以实现高可用)
-
所有节点时间同步
-
节点间网络通畅(开放4369, 25672, 5672, 15672, 61613等端口)
-
相同的Erlang cookie(位于
/var/lib/rabbitmq/.erlang.cookie)
集群配置步骤
-
安装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 -
配置主机名解析
确保所有节点可以相互解析主机名,编辑/etc/hosts:192.168.1.10 rabbitmq-node1 192.168.1.11 rabbitmq-node2 192.168.1.12 rabbitmq-node3 -
同步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 -
组建集群
将节点加入集群:# 在节点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
镜像队列策略配置
-
设置镜像队列策略
在所有队列上启用镜像,复制到所有节点: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"]}'
-
启用管理插件(可选)
如果需要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
代码示例
-
配置类
@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(); } } -
生产者示例
@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())); } } -
消费者示例
@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) { // 业务逻辑处理 } }
验证与测试
-
集群状态验证
# 检查集群状态 rabbitmqctl cluster_status # 检查策略 rabbitmqctl list_policies -
Spring Boot应用测试
创建测试类验证连接和消息发送:@SpringBootTest public class RabbitMQTest { @Autowired private MessageProducer producer; @Test public void testSendMessage() { producer.sendMessage("exchange.test", "routing.key", "Test Message"); // 添加断言验证消息发送成功 } }常见问题排查
-
节点无法加入集群
-
检查防火墙设置
-
验证Erlang cookie是否一致
-
确认主机名解析正确
-
-
镜像队列同步失败
-
检查网络连接
-
确认磁盘空间充足
-
验证RabbitMQ版本一致性
-
-
Spring Boot连接失败
-
检查配置的地址和端口
-
验证用户名和密码
-
确认虚拟主机存在
-
-
消息丢失问题
-
启用发布者确认
-
配置持久化队列和消息
-
实现消费者确认机制
-
-
性能问题
-
适当调整线程池大小
-
考虑使用批量消息处理
-
监控系统资源使用情况
-
通过以上配置和代码示例,我们应该能够成功搭建RabbitMQ镜像队列集群,并在Spring Boot应用中连接和使用该集群。记得根据实际生产环境调整配置参数,并进行充分的测试。
1863

被折叠的 条评论
为什么被折叠?



