1.RabbitMQ逻辑架构有哪些?
-
分为server端(也称为Broker)和client端
server端:
-
Broker:RabbitMQ服务器,用于对外提供服务。客户端(生产者及消费者)使用RabbitMQ消息中间件均需要连接到Broker,使用Rabbit的消息队列服务。
-
Virtual Host:Broker的虚拟机,提供多租户功能,实现租户的权限分离。
-
Exchange:消息交换器,指定消息发送规则及发送到指定的消息队列。
-
Queue:消息队列,用于存储消息。
-
RoutingKey:路由Key。生产者将消息发送给交换器的时候,一般会指定一个RoutingKey,用来指定这个消息的路由规则。
-
Binding:绑定器,用于将Exchange和Queue串联起来,Exchange通过Binding可以将消息路由到指定的Queue中。
client端:
-
Producer(消息生产者):生成消息,通过Channel(信道)将消息发送给Exchange。
-
Consumer(消息消费者):接受消息的程序。消费者监听RabbitMQ中的Queue中的消息,然后去消费。消息会一直留在队列里,直到被消费者消费。
2.介绍一下RabbitMQ有几种工作模式?
-
简单队列模型:一对一【一个队列对应一个消费者】
问题:生产者发送消息过多过快/消费端消费慢,会造成消息堆积的问题,消息不能被及时消费掉
-
工作队列模型:一对多【一个队列对应多个消费者】
同一个队列的多个消费者之间是竞争关系,消费的负载均衡策略是轮询
-
广播队列模型
fanout交换机,会把消息发送到每一个队列,使每一个消费端都能接收到同一条消息
-
定向队列模型
direct交换机,会按照routingkey的规则,把消息发送到相对应的队列中
-
通配符队列模型
topic交换机,会按照routingkey的规则,把消息发送到相对应的队列中,routingkey可使用通配符【* #】
3.消息可靠性方案*
-
方案一:从三个方面来保证:交换机、队列、消费者
1.生产者确保消息不丢失:Confirm和Return机制。Confirm机制主要用于确保消息从生产者发送到RabbitMQ的交换机;return退回模式:消息从交换机到队列失败会触发。
2.消费者保证消息不丢失:消息的ack确认机制和重试机制
-
方案二:消息持久化,保存到内存中
-
方案三:业务层面,通过本地消息表方式保证消息的可靠性投递
例如:生成订单,扣减库存的业务场景
第一步:生成订单时,向两张表加信息,业务表和消息表
业务表:相关订单信息
消息表:设置消息的状态--0未发送 1已发送 2失败
【将状态为0的消息进行mq发送】
第二步:消费端消费消息,消费完信息,通知消息已被消费
第三步:发送端收到消息被消费,修改消息状态为1
若消息失败,重试,次数过多,执行人工处理
多次发送时,要保证消息的幂等性
4.什么是幂等性问题?怎么确保消息幂等性?*
-
消息幂等性就是保证同一条消息只会消费一次,不重复消费同一条消息
-
redis加锁,setnx
-
乐观锁【版本号】
5.消息积压问题怎么解决?
-
问题出现的原因:消费端不消费/消费慢
-
最终的目的:1.让积压的消息再最短的时间内消费掉,2.保证消息不丢失
-
方案一:对消费端临时扩容,比如扩10倍/20倍,在最短时间内将消息消费完,再做其他处理进行排查,比如网络/服务器原因。
-
方案二:把mq消息设置过期时间ttl,消息到期会自动丢失,后续可通过人工的方式找到丢失的消息。
6.怎么确保消息顺序性?
-
一个队列对应一个消费者:将消息按照顺序发送到一个队列中,队列中的消息会先进先出,使一个消费者消费这个队列的消息,从而保证消费消息的顺序性。
7.哪些情况消息会成为死信?
-
消息过期(TTL)
-
队列满了
-
消费端拒收
8.如何实现消息延迟投递?
rabbitmq不支持延迟消息的发送
-
死信队列+TTL:过期的消息会进入到死信交换机,会将消息转发到死信队列中
-
在rabbitmq中使用延迟插件
-
redisson:通过lua脚本保证原子性
rabbitmq也能实现分布式事务
保证数据的最终一致性