RabbitMQ架构
死信队列
消息成为死信后会进入DLX死信交换器
① 信息被拒绝
② 信息超时
③ 超过了队列的最大长度
可以在队列或者消息本身设置超时时间,若两者都设置,以较小的为准
延迟队列
通过死信队列来实现
rabbitMQ如何确保消息发送和消息接受?
消息发送确认
1 ConfirmCallback
确认消息是否正确到达Exchange中
2 ReturnCallback
通过实现ReturnCallback接口启动消息失败返回。此接口是在交换机路由找不到队列时触发回调
消息接受确认
ACK机制,默认是自动确认,消息在被消费时,自动确认,此方法存在消息丢失的可能。即消息消费时就自动确认,消息消费过程中出现异常回滚,发送方并不知道,此消息丢失。
ACK.NONE 自动确认
ACK.AUTO 根据情况确认
ACK.MANUAL 手动确认
rabbitMQ事务消息原理
发送方事务
开启事务,发送多条数据。提交或回滚
消费方事务
ACK手动提交
最大努力通知方案
rabbitMQ如何提升消费速度
增加多个消费者
后端处理能力、并发冲突,以及处理顺序。
后端处理能力
主要指Redis时是否采用了多线程、IO复用等方式来进一步提升吞吐量。mysql数据库的处理量是否达到瓶颈。
另外还需要处理
并发冲突以及处理顺序
的问题,可能需要加锁,或者加时间判断。
使用多线程
原理和增加多个消费者一样,但是可以在同一个进程里面处理并发冲突和处理顺序,代码简易一些,但上限没有增加多个消费者高,因为只是在同一台主机上开多个线程。
调整发送、处理、确认之间的关系
提高Prefetch count
消息消费速度主要受到发送消息时间、消费者处理时间、消息Ack时间这几个时间的影响,如果一个消息走完这个流程再发送另一个的话,效率将会非常低。可以让消息在这几个时间内恰当的分配,让消息总是连续不断的被消费者接收处理,就可以提升消费者的消费速度。
批量ack
改变QOS值,可以缓冲多条消息到消费者端。
提升队列消费速度的解决方案
通过分析上边的这些方法,在使用RabbitMQ消费时可以遵循这样一个路径:
① 启用Prefetch count设置;
② 先1个消费者,1次只接收1条,处理完毕后再传输下一条,这样可以避免并发冲突和消息顺序问题;
③ 如果消费速度不满足要求,则1次接收多条,按接收顺序处理;
④ 如果消费速度还是不满足要求,则1次接收多条,并行处理;
⑤ 如果消费速度还是不满足要求,则启动多个消费者,并行处理。
⑥ 如果消费速度还是不满足要求,改需求,或者换别的中间件。
在这个过程中需要始终关注优化消费者及后端程序处理能力,比如优化SQL语句、使用缓存、使用负载均衡等等,加快处理速度就能提升消费速度,而且很多时候就是程序处理太耗时了。
关于重复数据、并发冲突、顺序处理问题的处理:
随时做好处理重复数据的准备,因为不只消费者端可能会触发消息的重复投递,发送端也可能重复发送消息,这个很难避免。
对于并发冲突问题,消费者进程内可以使用锁,跨消费者引入第三方机制来处理,比如使用Redis原子操作、数据库原子操作或者分布式锁。
对于顺序处理问题,最好没有这个需求;在同一个消费者内可以分组处理;在多个消费者时使用队列分组,每个队列绑定不同的Route key,不同Route key代表的消息之间没有顺序关联。波斯码再次提醒还要注意处理失败时的逻辑,避免重新投递消息的顺序问题。