#此文部分参考https://www.cnblogs.com/Terry-Wu/p/7644279.html
1.消息队列的介绍
1.什么是消息队列
从本质上说消息队列就是一个队列结构的中间件,也就是说消息放入这个中间件之后就可以直接返回,并不需要系统立即处理,而另外会有一个程序读取这些数据,并按顺序进行逐次处理。
也就是说当你遇到一个并发特别大并且耗时特别长同时还不需要立即返回处理结果,使用消息队列可以解决这类问题。
消息队列主要解决了应用耦合、异步处理、流量削锋等问题。
当前使用较多的消息队列有RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMq等,而部分数据库如Redis、Mysql以及phxsql也可实现消息队列的功能。
2.应用场景
数据冗余:比如订单系统,后续需要严格的进行数据转换和记录,消息队列可以把这些数据持久化的存储在队列中,然后有订单,后续处理程序进行获取,后续处理完之后在把这条记录进行删除来保证每一条记录都能够处理完成。
系统解耦:使用消息系统之后,入队系统和出队系统是分开的,也就说只要一天崩溃了,不会影响另外一台系统正常运转。
流量削峰:例如秒杀和抢购,我们可以配合缓存来使用消息队列,能够有效的顶住瞬间访问量,防止服务器承受不住导致崩溃。
异步通信:消息本身使用入队之后可以直接返回。
扩展性:例如订单队列,不仅可以处理订单,还可以给其他业务使用。
排序保证:有些场景需要按照产品的顺序进行处理比如单进单出从而保证数据按照一定的顺序处理,使用消息队列是可以的。
以上都是消息队列常见的使用场景,当然消息队列只是一个中间件,可以配合其他产品进行使用。
消息通讯:消息通讯是指,消息队列一般都内置了高效的通信机制,因此也可以用作消息通讯。比如实现点对点消息队列,或者聊天室等。
以上实际是消息队列的两种消息模式,点对点或发布订阅模式。
2.常用消息队列的介绍
现在比较常见的MQ产品主要是ActiveMQ、RabbitMQ、ZeroMQ、Kafka、MetaMQ、RocketMQ,当然还有很多其他的产品。因为个人水平有限,就简单的比较下这几种MQ的优缺点,作为自己选型的参考。
1.ZeroMQ
ZeroMQ号称是“史上最快的消息队列”,基于c语言开发的,可以在任何平台通过任何代码连接,通过inproc、IPC、TCP、TIPC、多播传送消息,支持发布-订阅、推-拉、共享队列等模式,高速异步I/O引擎。
根据官方的说法,ZeroMQ是一个简单好用的传输层,像框架一样的可嵌入的socket类库,使Socket编程更加简单、简洁、性能更高,是专门为高吞吐量/低延迟的场景开发的。ZeroMQ与其他MQ有着本质的区别,它根本不是消息队列服务器,更类似与一个底层网络通讯库,对原有Socket API进行封装,在使用的使用引入对应的jar包即可,可谓是相当灵活。
同时,因为它的简单灵活,如果我们想作为消息队列使用的话,需要开发大量代码。而且,ZeroMQ不支持消息持久化,其定位并不是安全可靠的消息传输,所以还需要自己编码保证可靠性。简而言之一句话,ZeroMQ很强大,但是想用好需要自己实现。
2.Rabbitmq
RabbitMQ 2007年发布,是一个在AMQP(高级消息队列协议)基础上完成的,可复用的企业消息系统,是当前最主流的消息中间件之一。
主要特性:
- 可靠性: 提供了多种技术可以让你在性能和可靠性之间进行权衡。这些技术包括持久性机制、投递确认、发布者证实和高可用性机制;
- 灵活的路由: 消息在到达队列前是通过交换机进行路由的。RabbitMQ为典型的路由逻辑提供了多种内置交换机类型。如果你有更复杂的路由需求,可以将这些交换机组合起来使用,你甚至可以实现自己的交换机类型,并且当做RabbitMQ的插件来使用;
- 消息集群:在相同局域网中的多个RabbitMQ服务器可以聚合在一起,作为一个独立的逻辑代理来使用;
- 队列高可用:队列可以在集群中的机器上进行镜像,以确保在硬件问题下还保证消息安全;
- 多种协议的支持:支持多种消息队列协议;
- 多语言支持:服务器端用Erlang语言编写,支持只要是你能想到的所有编程语言;
- 管理界面: RabbitMQ有一个易用的用户界面,使得用户可以监控和管理消息Broker的许多方面;
- 跟踪机制:如果消息异常,RabbitMQ提供消息跟踪机制,使用者可以找出发生了什么;
- 插件机制:提供了许多插件,来从多方面进行扩展,也可以编写自己的插件;
使用RabbitMQ需要:
- ErLang语言包
- RabbitMQ安装包
RabbitMQ可以运行在Erlang语言所支持的平台之上:
Solaris
BSD
Linux
MacOSX
TRU64
Windows NT/2000/XP/Vista/Windows 7/Windows 8
Windows Server 2003/2008/2012
Windows 95, 98
VxWorks
优点:
- 由于erlang语言的特性,mq 性能较好,高并发;
- 健壮、稳定、易用、跨平台、支持多种语言、文档齐全;
- 有消息确认机制和持久化机制,可靠性高;
- 高度可定制的路由;
- 管理界面较丰富,在互联网公司也有较大规模的应用;
- 社区活跃度高;
缺点:
- 尽管结合erlang语言本身的并发优势,性能较好,但是不利于做二次开发和维护;
- 实现了代理架构,意味着消息在发送到客户端之前可以在中央节点上排队。此特性使得RabbitMQ易于使用和部署,但是使得其运行速度较慢,因为中央节点增加了延迟,消息封装后也比较大;
- 需要学习比较复杂的接口和协议,学习和维护成本较高;
3.ActiveMQ
ActiveMQ介于ZeroMQ和RabbitMQ之间。类似于ZeroMQ,它可以部署于代理模式和P2P(点对点)模式。类似于RabbitMQ,它易于实现高级场景,而且只需付出低消耗。被誉为消息中间件的“瑞士军刀”。
支持OpenWire、Stomp、AMQP v1.0、MQTT v3.1、REST、Ajax、Webservice等多种协议;完全支持JMS1.1和J2EE 1.4规范(事务、持久化、XA消息);支持持久化到数据库。但是ActiveMQ不够轻巧,而且对于队列较多的情况支持不好,据说还有丢消息的情况。
目前已经有了其下一代消息产品Apollo。
4.Apollo
Apache称Apollo为最快、最强健的STOMP(简单"流"文本定向消息协议,它提供了一个可互操作的连接格式,允许STOMP客户端与任意STOMP消息代理(Broker)进行交互。STOMP协议由于设计简单,易于开发客户端,因此在多种语言和多种平台上得到广泛地应用)服务器。支持STOMP、AMQP、MQTT、OpenWire协议,支持Topic、Queue、持久订阅等消费形式,支持对消息的多种处理,支持安全性处理,支持REST管理API。。。功能列表很长,最大的弊病就是目前市场接收度不够,所以使用的并不广泛。
5.kafka
Apache Kafka是一个分布式消息发布订阅系统。它最初由LinkedIn公司基于独特的设计实现为一个分布式的提交日志系统( a distributed commit log),,之后成为Apache项目的一部分。Kafka系统快速、可扩展并且可持久化。它的分区特性,可复制和可容错都是其不错的特性。
主要特性:
- 快速持久化,可以在O(1)的系统开销下进行消息持久化;
- 高吞吐,在一台普通的服务器上既可以达到10W/s的吞吐速率;
- .完全的分布式系统,Broker、Producer、Consumer都原生自动支持分布式,自动实现负载均衡;
- 支持同步和异步复制两种HA;
- 支持数据批量发送和拉取;
- zero-copy:减少IO操作步骤;
- 数据迁移、扩容对用户透明;
- 无需停机即可扩展机器;
- 其他特性:严格的消息顺序、丰富的消息拉取模型、高效订阅者水平扩展、实时的消息订阅、亿级的消息堆积能力、定期删除机制;
使用Kafka需要:
- Java JDK
- Kafka安装包
优点:
- 客户端语言丰富,支持java、.net、php、ruby、python、go等多种语言;
- 性能卓越,单机写入TPS约在百万条/秒,消息大小10个字节;
- 提供完全分布式架构, 并有replica机制, 拥有较高的可用性和可靠性, 理论上支持消息无限堆积;
- 支持批量操作;
- 消费者采用Pull方式获取消息, 消息有序, 通过控制能够保证所有消息被消费且仅被消费一次;
- 有优秀的第三方Kafka Web管理界面Kafka-Manager;
- 在日志领域比较成熟,被多家公司和多个开源项目使用;
缺点:
- Kafka单机超过64个队列/分区,Load会发生明显的飙高现象,队列越多,load越高,发送消息响应时间变长
- 使用短轮询方式,实时性取决于轮询间隔时间;
- 消费失败不支持重试;
- 支持消息顺序,但是一台代理宕机后,就会产生消息乱序;
- 社区更新较慢;
6.RocketMQ
RocketMQ 是阿里巴巴在 2012 年开源的消息队列产品,用 Java 语言实现,在设计时参考了 Kafka,并做出了自己的一些改进,后来捐赠给 Apache 软件基金会,2017 正式毕业,成为 Apache 的顶级项目。RocketMQ 在阿里内部被广泛应用在订单,交易,充值,流计算,消息推送,日志流式处理,Binglog 分发等场景。经历过多次双十一考验,它的性能、稳定性和可靠性都是值得信赖的。
RocketMQ 有着不错的性能,稳定性和可靠性,具备一个现代的消息队列应该有的几乎全部功能和特性,并且它还在持续的成长中。
RocketMQ 有非常活跃的中文社区,大多数问题可以找到中文的答案。RocketMQ 使用 Java 语言开发,源代码相对比较容易读懂,容易对 RocketMQ 进行扩展或者二次开发。
RocketMQ 对在线业务的响应时延做了很多的优化,大多数情况下可以做到毫秒级的响应,如果你的应用场景很在意响应时延,那应该选择使用 RocketMQ。
RocketMQ 的性能比 RabbitMQ 要高一个数量级,每秒钟大概能处理几十万条消息。
RocketMQ 的劣势是与周边生态系统的集成和兼容程度不够。
3.总结
1.常用MQ的对比图
2.总结
其实对于这些消息队列的产品,每一种都在某一领域占有一席,在实际选型时,需要结合自身需求及MQ产品特征,综合考虑,更多细节和原理性的东西,还需在实践中见真知!
- 如果消息队列不是将要构建系统的重点,对消息队列功能和性能没有很高的要求,只需要一个快速上手易于维护的消息队列,建议使用 RabbitMQ。
- 如果系统使用消息队列主要场景是处理在线业务,比如在交易系统中用消息队列传递订单,需要低延迟和高稳定性,建议使用 RocketMQ。
- 如果需要处理海量的消息,像收集日志、监控信息或是埋点这类数据,或是你的应用场景大量使用了大数据、流计算相关的开源产品,那 Kafka 是最适合的消息队列。