RabbitMQ 整理
一、概述
RabbitMq是一种消息队列技术,最大的特点是实现了服务之间的高度解耦。因为消费并不需要确保提供方存在,只要消息传过来就行了。
二、为什么要使用rabbitmq
1、在分布式系统下具备异步、削峰、负载均衡等功能
2、拥有持久化机制,进程消息,队列中的信息也可以保存下来
3、实现消费者和生产者之间的解耦。
4、在高并发场景下,利用消息队列可以使得同步访问变为串行访问达到一定量的限流,利于数据库的操作。
5、可以使用消息队列达到异步下单的效果,排队中,后台进行逻辑下单。
三、使用rabbitmq的场景
服务间异步通讯
顺序消费
定时任务
请求削峰
四、如何确保消息正确地发送至Rabbitmq?如何确保消息接收方消费了消息
发送方确认模式confirm
-
发送方发送前, 将要发送到rabbitmq中的数据, 发送到的目标交换器名称目标队列名称等信息存入redis中一份
-
发送将数据发送到rabbitmq服务器
-
rabbitmq服务器接收到数据后会返回接收成功的消息给发送方
-
发送方接收到rabbitmq服务器返回的发送成功的消息后, 将redis中保存的数据删除
-
如果rabbitmq服务器宕机, 过一段时间发送方会接收到超时的异常信息, 捕获后从redis中从新获取之前保存的发送的内容, 发送的目标交换器名称和目标队列名称等信息, 从新发送数据给rabbitmq服务器
-
如果rabbitmq服务器依然宕机, 则一直重复上面的流程发送, 保证数据一定不会丢失
接收方确认机制 ack
-
mq服务器将数据发给接收方
-
接收方接收到数据后做业务操作
-
捕获业务操作代码中的异常
-
如果没有捕获到异常, 手动给mq返回消息, 说我接收到了, mq服务器会将给我发送的数据从队列中删除
-
如果捕获到异常, 手动给mq返回消息, 说我没有接收到, mq服务器会将刚才给我发送的数据重新发送.
五、如何避免消息重复投递或重复消费
在消息生产时,MQ 内部针对每条生产者发送的消息生成一个 inner-msg-id,作为去重的依据(消息投递失败并重传),避免重复的消息进入队列;
在消息消费时,要求消息体中必须要有一个 bizId(对于同一业务全局唯一,如支付 ID、订单 ID、帖子 ID 等)作为去重的依据,避免同一条消息被重复消费。
六、消息基于什么传输
由于 TCP 连接的创建和销毁开销较大,且并发数受系统资源限制,会造成性能瓶颈。RabbitMQ 使用信道的方式来传输数据。信道是建立在真实的 TCP 连接内的虚拟连接,且每条 TCP 连接上的信道数量没有限制。
七、消息如何分发?
若该队列至少有一个消费者订阅,消息将以循环(round-robin)的方式发送给消费者。每条消息只会分发给一个订阅的消费者(前提是消费者能够正常处理消息并进行确认)。通过路由可实现多消费的功能
8、消息怎么路由?
通过交换机和队列的绑定来实现路由。
fanout:如果交换器收到消息,将会广播到所有绑定的队列上
direct:如果路由键完全匹配,消息就被投递到相应的队列
topic:可以使来自不同源头的消息能够到达同一个队列。 使用 topic 交换器时,
可以使用通配符
9、如何确保消息不丢失?
消息持久化,当然前提是队列必须持久化RabbitMQ 确保持久性消息能从服务器重启中恢复的方式是,将它们写入磁盘上的一个持久化日志文件,当发布一条持久性消息到持久交换器上时,Rabbit 会在
消息提交到日志文件后才发送响应。一旦消费者从持久队列中消费了一条持久化消息,RabbitMQ 会在持久化日志中把这条消息标记为等待垃圾收集。如果持久化消息在被消费之前 RabbitMQ 重启,那么 Rabbit 会自动重建交换器和队列(以及绑定),并重新发布持久化日志文件中的消息到合适的队列。
10、使用 RabbitMQ 有什么好处?
1、服务间高度解耦
2、异步通信性能高
3、流量削峰
12、mq 的缺点
系统可用性降低
系统引入的外部依赖越多,越容易挂掉
本来你就是 A 系统调用 BCD 三个系统的接口就好了,人 ABCD 四个系统好好的,没啥问题,你偏加个 MQ 进来,万一MQ 挂了咋整?MQ 挂了,整套系统崩溃了,你不就完了么。
系统复杂性提高
一致性问题
A 系统处理完了直接返回成功了,人都以为你这个请求就成功了;但是问题是,要是 BCD 三个系统那里,BD 两个系统写库成功了,结果 C 系统写库失败了,咋整?你这数据就不一致了。
13、使用rabbitmq完成超时任务
在保存订单的时候,将订单id作为消息发送到rabbitmq延时队列中,如果超时了,会成为死信,发送到死信交换器,死信交换器中的订单会发送到死信队列。写个微服务监听私信队列,获取超时的订单号,可以执行一些业务逻辑。
14、rabbitmq模式
fanout模式---》广播模式
direct --》路由键模式/点对点模式
-
需要自定义交换机和队列并且完成绑定,而且需要设置routingKey
-
生产者发送消息到交换机后,交换机会根据发送时指定的routingKey将消息路由至绑定时设置的routingKey队列,穿的时候要把routingkey一块传过来,没有消息会丢失
5. Topic模式----》主题模式/通配符模式