消息中间件八股
消息中间件
RabbitMQ
消息不丢失
消息可能在发送到交换机、队列和消费者宕机时丢失
RabbitMQ提供publisher confirm(生产者确认)机制来避免消息丢失。消息发送到MQ后,会返回一个结果给生产者。

消息丢失后处理方式:
- 立即重发
- 记录日志
- 保存发送失败的数据,定时一起重发
消息持久化:MQ默认是内存存储消息,开启持久化可以保证消息不丢失
交换机持久化
1
2
3
4
5@Bean
public DirectExchange simpleExchange() {
// 交换机名称、是否持久化、没有queue绑定时是否自动删除
return new DirectExchange("simple.direct", true, false);
}队列持久化
1
2
3
4@Bean
public Queue simpleQueue() {
return QueueBuilder.durable("simple.queue").build();
}消息持久化
1
2
3
4Message msg = MessageBuilder
.withBody(message.getBytes())
.setDelieryMode(MessageDelieryMode.PERSISTENT) // 持久化
.build();
消费者确认:消费者收到消息返回ack,MQ收到ack后才会删除消息。如果多次获取消息失败,则将消息投递到异常交换机来处理
死信交换机/延迟队列
延迟队列:进入队列的消息会被延迟消费的队列,延迟队列=死信交换机+TTL(生存时间)
使用场景:超时订单取消、限时优惠、定时发布等
死信:过期消息、消费失败的消息、消息队列满了时最早的消息
死信交换机:接收死信的交换机
1 | |
消息堆积
生产者生产消息的速度大于消费者消费消息的速度时,就会导致堆积
解决方式:
- 增加消费者
- 消费者开启线程池加快消息处理速度
- 扩大队列容积
- 惰性队列:消息接收后存到磁盘中,时效性低
高可用
普通集群
- 集群中的节点共享交换机、队列信息,不包含队列中的消息
- 当访问集群某节点时,如果队列不在该节点,会从数据所在节点传递到当前节点并返回
- 队列所在节点宕机,队列中的消息就会丢失
镜像集群
- 主从模式,镜像节点做备份,主节点完成操作,主节点宕机由镜像节点替代
仲裁队列
- 主从模式,主从同步基于Raft协议,解决镜像节点主从同步时主节点宕机的问题