RabbitMQ简介
MQP 即Advanced Message Queuing Protocol(高级消息队列协议),是一个网络协议,是应用协议的一个开发标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制。2006年,AMQP规范发布。类比HTTP。
2007年,Rabbit技术公司基于AMQP标准开发的RabbitMQ 1.0发布。RabbitMQ采用Erlang语言开发。Erlang语言由Ericson设计,专门为开发高并发和分布式系统的一种语言,在电信领域使用广泛。
MQ的优势,为什么要使用MQ?
1.应用解耦(提高容错性和可维护性)
2.异步提速(与数据库串行、并行同理)
MQ的劣势
1.系统可用性降低(系统引入的外部依赖越多,系统稳定性越差,一旦MQ宕机会对业务造成影响)——>如何保证MQ的高可用?
2.系统复杂性提高 ——>如何保证消息不被丢失?
常见MQ及区别
MQ的工作模式
-
可伸缩性: 设计为分布式的,例如分为nameBervice和broker;broker负责Topic消息存储、管理和分发等功能;bs就是一个注册中心、维护所有Brokers信息。这样通过水平扩展就提升了吞吐量和容量了。
-
可靠性: 数据要磁盘落地,来做到可恢复、持久化。然后顺序写随机读来提高性能。
-
容错性: 多个机器中有的宕机后,要有类似zookeeper的的投票选举功能,确保集群稳定运行。
MQ常见面试题
1.1、场景\业务
例:
需求:1.下单后,30分钟为支付,取消订单,回滚库存
2.新用户注册成功7天后,发送短信问候
解:使用MQ高级特效—延迟队列(设置多久消费这条消息)
P:MQ中并未提供延迟队列功能。但是可以使用:TTL+死信队列组合实现延迟队列的效果
1.2、消息积压、重复消费、消息丢失等怎么处理?解决方案?
消息积压:
一般出现消息积压基本上分为几种情况:
-
消费者消费消息的速度赶不上生产速度,这总问题主要是业务逻辑没设计好消费者和生产者之间的平衡,需要改业务流程或逻辑已保证消费度跟上生产消息的速,譬如增加消费者的数量等。
-
消费者出现异常,导致一直无法接收新的消息,这种问题需要排查消费的逻辑是不是又问题,需要优化程序。
解决思路:
1.拆分MQ,生产者一个MQ,消费者一个MQ,写一个程序监听生产者的MQ模拟消费速度(譬如线程休眠),然后发送到消费者的MQ,如果消息积压则只需要处理生产者的MQ的积压消息,不影响消费者MQ
2.拆分MQ,生产者一个MQ,消费者一个MQ,写一个程序监听生产者的MQ,定义一个全局静态变量记录上一次消费的时间,如果上一次时间和当前时间只差小于消费者的处理时间,则发送到一个延迟队列(可以使用死信队列实现)发送到消费者的MQ,如果消息积压则只需要处理生产者的MQ的积压消息,不影响消费者MQ
3.使用Redis的List或ZSET做接收消息缓存,写一个程序按照消费者处理时间定时从Redis取消息发送到MQ
4.设置消息过期时间,过期后转入死信队列,写一个程序处理死信消息(重新如队列或者即使处理或记录到数据库延后处理)
重复消费:先说为什么会重复消费:正常情况下,消费者在消费消息的时候,消费完毕后,会发送一个确认消息给消息队列,消息队列就知道该消息被消费了,就会将该消息从消息队列中删除;
但是因为网络传输等等故障,确认信息没有传送到消息队列,导致消息队列不知道自己已经消费过该消息了,再次将消息分发给其他的消费者。
针对以上问题,一个解决思路是:保证消息的唯一性,就算是多次传输,不要让消息的多次消费带来影响;保证消息等幂性;
比如:在写入消息队列的数据做唯一标示,消费消息时,根据唯一标识判断是否消费过;
消息丢失:一.消息持久化
1.Exchange设置持久化:durable:true
2.Queue设置持久化
3.Message持久化发送
二.ACK确认机制
1.消息发送确认
2.消息接受确认
三.设置集群镜像模式
四.消息补偿机制
1.3、MQ使用场景、为什么使用MQ、MQ的优劣
1.4、使用MQ时遇到什么问题,怎么解决
进阶方向图: