赞
踩
RabbitMQ
而不是其它的MQ
?如图:
话术:
kafka
是以吞吐量高而闻名,不过其数据稳定性一般,而且无法保证消息有序性。我们公司的日志收集也有使用,业务模块中则使用的RabbitMQ
。
阿里巴巴的RocketMQ
基于Kafka
的原理,弥补了Kafka
的缺点,继承了其高吞吐的优势,其客户端目前以Java
为主。但是我们担心阿里巴巴开源产品的稳定性,所以就没有使用。
RabbitMQ
基于面向并发的语言Erlang
开发,吞吐量不如Kafka
,但是对我们公司来讲够用了。而且消息可靠性较好,并且消息延迟极低,集群搭建比较方便。支持多种协议,并且有各种语言的客户端,比较灵活。Spring
对RabbitMQ
的支持也比较好,使用起来比较方便,比较符合我们公司的需求。
综合考虑我们公司的并发需求以及稳定性需求,我们选择了RabbitMQ
。
RabbitMQ
如何确保消息的不丢失?话术:
RabbitMQ
针对消息传递过程中可能发生问题的各个地方,给出了针对性的解决方案:
RabbitMQ
提供了publisher confirm
机制
ConfirmCallback
函数RabbitMQ
会调用ConfirmCallback
通知消息的发送者,返回ACK
RabbitMQ
也会调用ConfirmCallback
通知消息的发送者,返回NACK
RabbitMQ
提供了publisher return
机制
ReturnCallback
函数RabbitMQ
会调用ReturnCallback
通知发送者,告知失败原因MQ
宕机也可能导致丢失消息:
RabbitMQ
提供了持久化功能,集群的主从备份功能
RabbitMQ
会将交换机、队列、消息持久化到磁盘,宕机重启可以恢复消息SpringAMQP
基于RabbitMQ
提供了消费者确认机制、消费者重试机制,消费者失败处理策略:
Spring
返回ACK
给RabbitMQ
,消息才被移除Spring
返回NACK
或者不返回结果,消息不被异常MQ
队列,然后投递给其它消费者。Spring
提供的消费者重试机制,则是在处理失败后不返回NACK
,而是直接在消费者本地重试。多次重试都失败后,则按照消费者失败处理策略来处理消息。避免了消息频繁入队带来的额外压力。Spring
提供了Republish
策略,在多次重试都失败,耗尽重试次数后,将消息重新投递给指定的异常交换机,并且会携带上异常栈信息,帮助定位问题。RabbitMQ
如何避免消息堆积?话术:
消息堆积问题产生的原因往往是因为消息发送的速度超过了消费者消息处理的速度。因此解决方案无外乎以下三点:
1)提高消费者处理速度
消费者处理速度是由业务代码决定的,所以我们能做的事情包括:
优点:成本低,改改代码即可
缺点:开启线程池会带来额外的性能开销,对于高频、低时延的任务不合适。推荐任务执行周期较长的业务。
2)增加更多消费者
一个队列绑定多个消费者,共同争抢任务,自然可以提供消息处理的速度。
优点:能用钱解决的问题都不是问题。实现简单粗暴
缺点:问题是没有钱。成本太高
3)增加队列消息存储上限
在RabbitMQ
的1.8
版本后,加入了新的队列模式:Lazy Queue
这种队列不会将消息保存在内存中,而是在收到消息后直接写入磁盘中,理论上没有存储上限。可以解决消息堆积问题。
优点:磁盘存储更安全;存储无上限;避免内存存储带来的Page Out
问题,性能更稳定;
缺点:磁盘存储受到IO
性能的限制,消息时效性不如内存模式,但影响不大。
RabbitMQ
如何保证消息的有序性?话术:
其实RabbitMQ
是队列存储,天然具备先进先出的特点,只要消息的发送是有序的,那么理论上接收也是有序的。不过当一个队列绑定了多个消费者时,可能出现消息轮询投递给消费者的情况,而消费者的处理顺序就无法保证了。
因此,要保证消息的有序性,需要做的下面几点:
MQ
消息被重复消费?话术:
消息重复消费的原因多种多样,不可避免。所以只能从消费者端入手,只要能保证消息处理的幂等性就可以确保消息不被重复消费。
而幂等性的保证又有很多方案:
id
,在本地记录消息表及消息状态,处理消息时基于数据库表的id
唯一性做判断RabbitMQ
的高可用?话术:
要实现RabbitMQ
的高可用无外乎下面两点:
RabbitMQ
的镜像集群,做好主从备份。当然也可以使用仲裁队列代替镜像集群。MQ
可以解决那些问题?话术:
RabbitMQ
能解决的问题很多,例如:
MQ
中,作为缓冲区。后端的业务根据自己的处理能力从MQ
中获取消息,逐个处理任务。流量曲线变的平滑很多RabbitMQ
的死信队列或者DelayExchange
插件,可以实现消息发送后,延迟接收的效果。服务之间的业务耦合。同时还提高了业务性能。
MQ
中,作为缓冲区。后端的业务根据自己的处理能力从MQ
中获取消息,逐个处理任务。流量曲线变的平滑很多RabbitMQ
的死信队列或者DelayExchange
插件,可以实现消息发送后,延迟接收的效果。Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。