这是我参与「第五届青训营 」伴学笔记创作活动的第 15 天
本篇笔记主要记录一下RabbitMQ的学习知识
1、延时队列底层实现
对队列和消息设置TTL控制消息的生存时间,如果超时消息将会变为dead letter。
-
对队列属性设置,这样队列中所有消息都有相同的过期时间
-
对消息单独设置过期时间
Ps:消息过期后会进入死信队列,监听死信队列消费即可实现延迟队列
2、使用RabbitMQ注意
消息的丢失、消息的重复使用、消息的重新发送......
3、如何确保消息正确发送到队列以及如何确保消费消息
-
发送方确认模式
将信道设置为confirm模式,会在信道上发布的消息都会设置一个唯一ID。当消息发送到目的队列后,或者消息被写入磁盘则信道会发送一个确认给生产者 (包括ID)
这个确认模式是异步的,可以一边等待确认一边继续发送消息
当确认消息到达生产者程序后,生产者应用的回调方法就会被触发来处理确认消息
-
接收方确认机制
消费者在接收到消息后都要确认,只有消费者确认了之后,MQ才可以把消息从队列中安全删除
这里没有超时机制,只要连接不中断,就可以保证消费者有足够的时间处理消息,保证了数据一致性
但是如果在确认消息之前断开了连接或者取消订阅,RabbitMQ就会认为消息没有被发送,则会重新分发给下一个订阅的消费者,存在消费重复的隐患
如果消费者接收到消息却没有确认消息,连接也未断开,则RabbitMQ认为该消费者繁忙。则不会给该消费者分发更多的消息
4、如何避免消息重发或重复消费
在消息生产时,MQ内部对每一个消息生成一个id作为去重的机制,避免重复的消息进入队列,而且在消费时,要求消息体中含有一个特定id,这个id在一个业务中全局唯一,作为去重依据,避免同一条消息被重复消费
5、消息基于什么传输
因为TCP连接的创建销毁开销大,切并发数受系统限制
RabbitMQ使用信道方式传输数据,而信道是建立在真实的TCP连接内的虚拟连接,每一条TCP连接上的信道数量是无限制的
6、消息如何分发
一个生产者,多个消费者。 多个消费者时,是轮询机制,依次分发给消费者(每个消费者按顺序依次消费)
no_act = True , 消费者不发送确认信息,RabbitMQ从发送消息队列后,不管消费者是否处理完,删除queue
no_act = False,RabbitMQ等待消费者的callback处理完,发送确认信息,如果此时消费者down了,则RabbitMQ把消息轮询发送给下一个消费者,等待确认才会删除queue
去掉no_act=True,需要在回调函数中新增代码,手动向RabbitMQ发送确认信息
7、消息如何路由
- Direct:直连模式
- Topic:转发模式,转发模式下使用通配符bingKey: '*' 匹配一个单词,'#' 匹配0/多个单词
- Fanout:广播模式
8、如何确保消息不丢失
-
生产者丢失消息
RabbitMQ事务;但是缺点就是事务开启会变为同步阻塞,耗费性能
-
RabbitMQ自己丢失数据
持久化
-
消费者丢失数据
使用RabbitMQ的ACK机制,关闭自动ACK,在确保处理完消息后在代码中手动调用ACK
9、使用RabbitMQ的好处
-
削峰
缓冲系统压力,可以将过多的请求压入RabbitMQ之后进行消费
-
异步
-
解耦
10、使用RabbitMQ的缺点
消息丢失、重复消费等等问题
人生苦短,不如go浪一下。