在高并发业务场景下,典型的阿里双11秒杀等业务,消息队列中间件在流量削峰、解耦上有不可替代的作用。
今天我们一起来探讨:
- 市场上全量的消息队列究竟有哪些?
- 以及消息队列的优劣势比较。
- 以及什么样的业务场景选择哪类消息队列?
目前主流的MQ产品
ZeroMQ
号称最快的消息队列系统,尤其针对大吞吐量的需求场景。
扩展性好,开发比较灵活,采用C语言实现,实际上只是一个socket库的重新封装,如果做为消息队列使用,需要开发大量的代码。ZeroMQ仅提供非持久性的队列,也就是说如果down机,数据将会丢失。其中,Twitter的Storm中使用ZeroMQ作为数据流的传输。
Kafka大数据的杀手锏
谈到大数据领域内的消息传输,则绕不开Kafka,这款为大数据而生的消息中间件,以其百万级TPS的吞吐量名声大噪,迅速成为大数据领域的宠儿,在数据采集、传输、存储的过程中发挥着举足轻重的作用,被LinkedIn,Uber, Twitter, Netflix等大公司所采纳,而storm,spark,flink等大数据流处理或批处理平台都有Kafka的相关插件支持。
Apache Kafka它最初由LinkedIn公司基于独特的设计实现为一个分布式的提交日志系统( a distributed commit log),之后成为Apache项目的一部分。
Kafka优点:
- 客户端语言丰富,支持java、.net、php、ruby、python、go等多种语言;
- 性能卓越,单机写入TPS约在百万条/秒,消息大小10个字节;
- 提供完全分布式架构, 并有replica机制, 拥有较高的可用性和可靠性, 理论上支持消息无限堆积;
- 支持批量操作;
- 消费者采用Pull方式获取消息, 消息有序, 通过控制能够保证所有消息被消费且仅被消费一次;
- 有优秀的第三方Kafka Web管理界面Kafka-Manager;
- 在日志领域比较成熟,被多家公司和多个开源项目使用;
kafka缺点:
- Kafka单机超过64个队列/分区,Load会发生明显的飙高现象,队列越多,load越高,发送消息响应时间变长
- 使用短轮询方式,实时性取决于轮询间隔时间;
- 消费失败不支持重试;
- 支持消息顺序,但是一台代理宕机后,就会产生消息乱序;
- 社区更新较慢;
RabbitMQ
RabbitMQ 2007年发布,是一个在AMQP(高级消息队列协议)基础上完成的,可复用的企业消息系统,是当前最主流的消息中间件之一。
使用RabbitMQ需要:
- ErLang语言包
- RabbitMQ安装包
RabbitMQ优点:
- 由于erlang语言的特性,mq 性能较好,高并发;
- 健壮、稳定、易用、跨平台、支持多种语言、文档齐全;
- 有消息确认机制和持久化机制,可靠性高;
- 高度可定制的路由;
- 管理界面较丰富,在互联网公司也有较大规模的应用;
- 社区活跃度高;
RabbitMQ缺点:
- 尽管结合erlang语言本身的并发优势,性能较好,但是不利于做二次开发和维护;
- 实现了代理架构,意味着消息在发送到客户端之前可以在中央节点上排队。此特性使得RabbitMQ易于使用和部署,但是使得其运行速度较慢,因为中央节点增加了延迟,消息封装后也比较大;
- 需要学习比较复杂的接口和协议,学习和维护成本较高;
RocketMQ
RocketMQ出自 阿里公司的开源产品,用 Java 语言实现,在设计时参考了 Kafka,并做出了自己的一些改进。
RocketMQ在阿里集团被广泛应用在订单,交易,充值,流计算,消息推送,日志流式处理,binglog分发等场景。
使用RocketMQ需要:
- Java JDK
- 安装git、Maven
- RocketMQ安装包
RocketMQ优点:
- 顺序性,它支持顺序性,可以做到局部有序,在单线程内使用该生产者发送的消息按照发送的顺序到达服务器并存储,并按照相同顺序被消费,但前提是这些消息发往同一服务器的同一个分区
- 实时性:采取长轮询+PULL消费消息,你可以自己决定如何在响应性和吞吐量之间做平衡,配合合理的参数设置来获得更高的响应时间,实时性不低于PUSH方式
- 提供了丰富的拉取模式
- 支持10亿级别的消息堆积,不会因为堆积导致性能下降
- 高效的订阅者水平扩展机制
RocketMQ缺点:
- 支持的客户端语言不多,目前是java及c++,其中c++不成熟;
- RocketMQ社区关注度及成熟度也不及前两者;
- 没有web管理界面,提供了一个CLI(命令行界面)管理工具带来查询、管理和诊断各种问题;
- 没有在 mq 核心中去实现JMS等接口;
ActiveMQ
历史悠久的开源项目,是Apache下的一个子项目。已经在很多产品中得到应用,实现了JMS1.1规范,可以和spring-jms轻松融合,实现了多种协议,不够轻巧(源代码比RocketMQ多),支持持久化到数据库,对队列数较多的情况支持不好。
Redis
做为一个基于内存的K-V数据库,其提供了消息订阅的服务,可以当作MQ来使用,目前应用案例较少,且不方便扩展。
消息队列的业务场景选择
1.Kafka
Kafka主要特点是基于Pull的模式来处理消息消费,追求高吞吐量,一开始的目的就是用于日志收集和传输,适合产生大量数据的互联网服务的数据收集业务。
是一个不折不扣的大数据通道,追求高吞吐,不过存在丢消息的可能。
2.RocketMQ
天生为金融互联网领域而生,对于可靠性要求很高的场景,尤其是电商里面的订单扣款,以及业务削峰,在大量交易涌入时,后端可能无法及时处理,所以MQ的大量消息堆积功能就可以发挥作用。
RoketMQ在稳定性上可能更值得信赖,这些业务场景在阿里双11已经经历了多次考验,如果你的业务有上述并发场景,建议可以选择RocketMQ。
3.RabbitMQ
RabbitMQ :结合erlang语言本身的并发优势,性能较好,社区活跃度也比较高,但是不利于做二次开发和维护。
消息中间件总结
1.中小型公司,建议选RabbitMQ,一方面,erlang语言天生具备高并发的特性,而且他的管理界面用起来十分方便,但是不利于做二次开发和维护。
所幸,RabbitMQ的社区十分活跃,可以解决开发过程中遇到的bug,这点对于中小型公司来说十分重要。中小型软件公司不如互联网公司,数据量没那么大,选消息中间件,应首选功能比较完备的,推荐RabbitMQ。
2.大型公司,根据具体使用在rocketMq和kafka之间二选一。最后根据业务场景选择,如果有日志采集功能,肯定是首选kafka了。
陈睿mikechen
10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。
关注「mikechen」公众号,获取更多技术干货!
后台回复【面试】即可获取《史上最全阿里Java面试题总结》,后台回复【架构】,即可获取《阿里架构师进阶专题全部合集》