RabbitMQ
背景
rabbitmq实际上是实现了AMQP高级消息队列协议的消息队列服务,使用的是erlang语言
因为使用的erlang语言,所以rabbitmq要比其他的mq在高并发方面突出的多
优势
是除了Qpid,以外唯一一个实现了AMQP标准的消息服务器
可靠性,rabbitmq的持久化的支持,保证了消息的稳定性
高并发,正是因为rabbitmq使用erlang语言开发。erlang是为电话交换机开发的语言,天生自带高并发光环,
集群部署简单,也是因为erlang的原因
社区活跃
应用场景
秒杀,因为支持持久化和erlang的高并发,所以在秒杀的活动中可以起到很好的缓冲的作用
常见的问题
如何保证消息不重复消费
-
消息的重复消费的主要问题是在于回馈机制(ack)
-
主要还是区分业务场景来说
- 如果消息是往数据库写,先根据主键查询下,如果已经存在了,那么update下。
- 如果消息是往redis中写,那么不用管,redis支持天然的幂等性
- 如果是其他场景,可以使用全局唯一id,当消费完成,在redis中根据这个id查找,如果不存在,显示这个消息已经消费了,不需要处理;如果存在那么就处理,然后将对应的内容在redis中删除
如何保证消息的确切消费
-
生产者搞丢了消息
- 主要策略就是启用confirm机制。confirm机制和事务最大的区别在于事务是同步的,会阻塞后续的消息生产。而confirm机制是异步的,不会影响后续的操作
-
rabbitmq搞丢了消息
- 开启rabbitmq的持久化机制。两部分的持久化,一部分是队列的持久化,保证持久化queue的元数据;一部分是发送消息的时候将消息的deliveryMode设置为2,也就是将消息设置为持久化的
-
消费者搞丢了消息
- 需要使用rabbimq提供的ack机制,需要我们关闭自动ack,然后自己处理完逻辑后,手动ack。
消息堆积在mq中怎么办
-
排查什么原因导致消息堆积,是因为broker和consumer的网络问题,还是因为consumer本身就有问题
-
线上问题:有可能是堆积了百万条数据,可以临时紧急扩容
- 先将出问题的consumer修复
- 新建exchange,其中对应的队列是之前的数倍
- 然后写临时的consumer,将堆积的消息分发,或者保存下来
- 然后恢复原来的部署架构,将堆积的消息重新发送
工作模式
direct
- 默认交换机
- 声明队列
- 交换机和队列不需要绑定
fanout
- 指定交换机
- 指定队列
- 交换机和队列绑定
topic
- 指定交换机
- 指定队列
- 交换机和队列绑定
- 需要routingkey
header
- 指定队列
- 添加header
XMind - Trial Version