集群搭建
- 比较简单,有空再尝试搭建,大概步骤如下
- 准备3台rabbitmq
- 保证相互之间可以ping通,最好修改hostname便于分辨
- 复制 erlang 的 cookie(RabbitMQ 集群需要在每个从节点上使用与主节点一样的 ErLang Cookie),参考如下:
scp /var/lib/rabbitmq/.erlang.cookie root@node2:/var/lib/rabbitmq/.erlang.cookie
scp /var/lib/rabbitmq/.erlang.cookie root@node3:/var/lib/rabbitmq/.erlang.cookie
- 重启3台mq
- node2执行相关命令加入node1,node3加入node2
- 任意一台mq上查看集群状态,ok
- 创建账户、设置角色、权限等
- 解除某个节点,执行相关命令即可
配置镜像队列
- 默认搭好的集群,每个节点之间,数据是不同步的,需要配置镜像队列
- 在管理界面添加策略:保持集群中始终有2台机器数据自动同步,所有创建的队列必须带上指定前缀才生效
Nginx+Keepalived实现MQ负载均衡+HA
- MQ默认不支持负载均衡,需要配合Nginx或HAProxy实现负载均衡,如果要两台Nginx,则还需要使用Keepalived实现Nginx的HA以及虚拟IP,最终用户通过虚拟IP就可以负载均衡到所有MQ节点
- 有空再实战,架构图如下:
备份交换机
- 对于已经到达队列但无法被正常消费的消息,可以设置死信队列来存储这些消息
- 但是对于不可路由的消息,根本没有机会进入到队列,因此无法使用死信队列
- 在 RabbitMQ 中,有一种备份交换机的机制存在,可以很好的应对这个问题
- 备份交换机就是用于处理
无法被普通交换机路由
的消息 - 需要注意:当同时设置了消息回退机制和备份交换机时,会优先采用备份交换机
- 下图中,无法路由的消息将通过备份交换机发送给告警队列,示意图:
@Bean
public DirectExchange confirmExchange() {
ExchangeBuilder exchangeBuilder = ExchangeBuilder.directExchange(CONFIRM_EXCHANGE_NAME)
.durable(true)
.alternate(BACKUP_EXCHANGE_NAME);
return exchangeBuilder.build();
}
@RabbitListener(queues = WARNING_QUEUE_NAME)
public void receiveWarningMsg(Message message) {
String msg = new String(message.getBody());
log.warn("报警发现不可路由消息:{}", msg);
}
优先队列
- 是指队列中的消息具备优先级,优先级高的消息将先被消费
- 使用场景:订单催付,大客户先催付
- 创建队列时指定参数:
QueueBuilder.durable(WARNING_QUEUE_NAME).maxPriority(10).build()
(优先级在0-255之间) - 发送消息时指定优先级即可
惰性队列
- 惰性队列会尽可能的将消息存入
磁盘
中,而在消费者消费到相应的消息时才会被加载到内存中 - 当消费者由于各种各样的原因(比如消费者下线、宕机亦或者是由于维护而关闭等)而致使长时间内不能消费消息造成堆积时,惰性队列就很有必要了
- 在创建队列时设置即可:
QueueBuilder.durable(BACKUP_QUEUE_NAME).lazy().build();
- MQ从 3.6.0 版本引入了惰性队列的概念
Federation exchange 和 shovel