消息队列的优点
削峰:
比如:在一天中2点的访问量突然爆发,没用MQ的话系统,根本承受不住这种压力,数据库直接down掉,有了MQ会把突增的请求放入,慢慢消费掉。
解耦:
比如说有两个服务A和B,A把消息放到MQ中,B来进行消费。A只需要把消息放到MQ中,不用关心否有人进行消费。B只需要有消息就从MQ中取来消费,不用关心A的情况。
异步:
请求放到MQ中,请求就算结束了,可以立刻返回响应给客户端,用户体验极好,消费者异步去消费消息。
消息队列的缺点
系统可用性降低
系统外部依赖越多,越容易挂掉。万一MQ挂了,那系统流程就断了。
系统复杂度提高产生的问题
怎么保证消息有没有重复消费(幂等性)?
怎么保证消息不丢失?
怎么保证消息传递的时序性?
一致性问题
A放到MQ就返回成功了,B写库成功,C写库失败,数据就不一致了。
常见消息队列对比
特性 | ActiveMQ | RabbitMQ | RocketMQ | Kafka |
---|---|---|---|---|
单机吞吐量 | 万级,比RocketMQ,Kafka低一个数量级 | 同ActiveMQ | 10万级,支撑高吞吐 | 10万级,高吞吐,一般配合大数据类的系统来进行实时数据计算,日志采集等场景 |
topic数量对吞吐量的影响 | topic可以达到几百/几千的级别,吞吐量会有较小幅度的下降,这是RocketMQ的一大优势,在同等机器下,可以支撑大量的topic | topic从几十到几百个时候,在吞吐量会大幅度下降,在同等机器下,Kafka尽量保证topic数量不要过多,如果要支撑大规模的topic,需要增加更多的机器资源 | ||
时效性 | ms级 | 微妙级,这是RabbitMQ的一大特点,延迟最低 | ms级 | 延迟在ms级以内 |
可用性 | 高,基于主从架构实现高可用 | 同ActiveMQ | 非常高,分布式架构 | 非常高,分布式,一个数据多个副本,少数机器挂掉,不会丢失数据,不会导致不可用 |
消息可靠性 | 有较低的概率丢失数据 | 基本不丢失 | 经过参数优化配置,可以做到0丢失 | 同RocketMQ |
功能支持 | MQ领域的功能及其完备 | 基于erlang开发,并发能力很强,性能极好,延时很低 | MQ功能较为完善,还是分布式的,拓展性好 | 功能较为简单,主要支持简单地MQ功能,在大数据领域的实时计算以及日志采集被大规模使用 |
综上,各种对比之后,有如下建议:
一般的业务系统要引入 MQ,最早大家都用 ActiveMQ,但是现在确实大家用的不多了,没经过大规模吞吐量场景的验证,社区也不是很活跃,不推荐用这个了;
后来大家开始用 RabbitMQ,但是确实 erlang 语言阻止了大量的 Java 工程师去深入研究和掌控它,对公司而言,几乎处于不可控的状态,但是确实人家是开源的,比较稳定的支持,活跃度也高;
不过现在确实越来越多的公司会去用 RocketMQ,确实很不错,毕竟是阿里出品,但社区可能有突然黄掉的风险(目前 RocketMQ 已捐给 Apache,但 GitHub 上的活跃度其实不算高)对自己公司技术实力有绝对自信的,推荐用 RocketMQ,否则回去老老实实用 RabbitMQ 吧,人家有活跃的开源社区,绝对不会黄。
所以中小型公司,技术实力较为一般,技术挑战不是特别高,用 RabbitMQ 是不错的选择;大型公司,基础架构研发实力较强,用 RocketMQ 是很好的选择。
如果是大数据领域的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范。