-
2018-05-15 09:56:25
ActiveMQ Joram HornetQ OpenMQ MuleMQ SonicMQ RabbitMQ ZeroMQ 关注度 高 中 中 中 低 低 高 中 成熟度 成熟 比较成熟 比较成熟 比较成熟 新产品无成功案例 成熟 成熟 不成熟 所属社区/公司 Apache OW2 Jboss Sun Mule Progress 社区活跃度 高 中 中 低 高 低 高 低 文档 多 多 中 中 少 少 多 中 特点 功能齐全,被大量开源项目使用 在Linux平台上直接调用操作系统的AIO,性能得到很大的提升 性能非常好,与MuleESB无缝整合 性能优越的商业MQ 由于Erlang语言的并发能力,性能很好 低延时,高性能,最高43万条消息每秒 授权方式 开源 开源 开源 开源 商业 商业 开源 开源 开发语言 Java Java Java Java Java Java Erlang C 支持的协议 OpenWire、STOMP、REST、XMPP、AMQP JMS JMS JMS JMS JMS AMQP TCP、UDP 客户端支持语言 Java、C、C++、Python、PHP、Perl、.net等 Java Java Java Java Java、C、C++、.net Java、C、C++、Python、PHP、Perl等 python、java、php、.net等 持久化 内存、文件、数据库 内存、文件 内存、文件 内存、文件 内存、文件 内存、文件、数据库 内存、文件 在消息发送端保存 事务 支持 支持 支持 支持 支持 支持 不支持 不支持 集群 支持 支持 支持 支持 支持 支持 支持 不支持 负载均衡 支持 支持 支持 支持 支持 支持 支持 不支持 管理界面 一般 一般 无 一般 一般 好 无 无 部署方式 独立、嵌入 独立、嵌入 独立、嵌入 独立、嵌入 独立 独立 独立 独立 评价 成熟稳定,开源首选 依赖容器,不适合跨语言调用 推出的时间不长,尚无使用案例,不适合跨语言调用 依赖容器,不适合跨语言调用 推出的时间不长,无成功案例,目前仅支持Java 成熟稳定 Queue的数量大于50后,高并发下无法持续稳定的提供服务 不支持事务、集群,并且消息不能在服务端持久化
更多相关内容 -
常用消息中间件选择
2022-02-27 17:20:47文章目录一、ActiveMQ二、RabbitMQ三、RocketMQ四、Kafka五、ZeroMQ六、主要消息中间件的比较 有哪些主流的消息中间件? 当前业界比较流行的开源消息中间件包括:ActiveMQ、RabbitMQ、RocketMQ、Kafka、ZeroMQ等。 ...有哪些主流的消息中间件?
当前业界比较流行的开源消息中间件包括:ActiveMQ、RabbitMQ、RocketMQ、Kafka、ZeroMQ等。
其中应用最为广泛的要数RabbitMQ、RocketMQ、Kafka 这三款。
Redis在某种程度上也可以是实现类似 “Queue” 和“ Pub/Sub” 的机制,严格意义上不算消息中间件。
一般的业务系统要引入 MQ,最早大家都用 ActiveMQ,但是现在确实大家用的不多了,没经过大规模吞吐量场景的验证,社区也不是很活跃,所以大家还是算了吧,不推荐用这个了。
后来大家开始用 RabbitMQ,但是确实 erlang 语言阻止了大量的 Java 工程师去深入研究和掌控它,对公司而言,几乎处于不可控的状态,但是确实人家是开源的,比较稳定的支持,活跃度也高。
不过现在确实越来越多的公司,会去用 RocketMQ,确实很不错(阿里出品),但社区可能有突然黄掉的风险,对自己公司技术实力有绝对自信的,推荐用 RocketMQ,否则回去老老实实用 RabbitMQ 吧,人家有活跃的开源社区,绝对不会黄。
所以中小型公司,技术实力较为一般,技术挑战不是特别高,用 RabbitMQ 是不错的选择;大型公司,基础架构研发实力较强,用 RocketMQ 是很好的选择。
如果是大数据领域的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范。
一、ActiveMQ
Apache下的一个子项目。使用Java完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现,少量代码就可以高效地实现高级应用场景。可插拔的传输协议支持,比如:in-VM, TCP, SSL, NIO, UDP, multicast, JGroups and JXTA transports。
ActiveMQ、RabbitMQ、ZeroMQ均支持常用的多种语言客户端 C++、Java、.Net,、Python、 Php、 Ruby等。
ActiveMQ只需要操作系统支持Java虚拟机,便可执行。
ActiveMQ可以很容易内嵌到使用Spring的系统里面去通过了常见J2EE服务器的测试。
JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。其丰富的 API 、多种集群构建模式使得他成为业界老牌消息中间件,在中小型企业中应用广泛!
优点:
- ActiveMQ采用消息推送方式,所以最适合的场景是默认消息都可在短时间内被消费。数据量越大,查找和消费消息就越慢,消息积压程度与消息速度成反比。
- 单机吞吐量万级,时效性 ms 级,可用性高,基于主从架构实现高可用性,消息可靠性:有较低的概率丢失数据。
缺点:
- 吞吐量低。由于 ActiveMQ 需要建立索引,导致吞吐量下降。这是无法克服的缺点,只要使用完全符合 JMS 规范的消息中间件,就要接受这个级别的TPS。
- 无分片功能。这是一个功能缺失,JMS 并没有规定消息中间件的集群、分片机制。而由于 ActiveMQ 是伟企业级开发设计的消息中间件,初衷并不是为了处理海量消息和高并发请求。如果一台服务器不能承受更多消息,则需要横向拆分。ActiveMQ 官方不提供分片机制,需要自己实现。
- 官方社区现在对 ActiveMQ 5.x 维护越来越少,高吞吐量场景较少使用。
二、RabbitMQ
使用Erlang编写的一个开源的消息队列,本身支持很多的协议:AMQP,XMPP,SMTP,STOMP,也正是如此,使的它变的非常重量级,更适合于企业级的开发。同时实现了Broker架构,核心思想是生产者不会将消息直接发送给队列,消息在发送给客户端时先在中心队列排队。对路由(Routing),负载均衡(Load balance)、数据持久化都有很好的支持。多用于进行企业级的ESB整合。
RabbitMQ 开始是用在电信业务的可靠通信的,也是少有的几款支持AMQP协议的产品之一。
优点:
- 轻量级,快速,部署使用方便
- 支持灵活的路由配置。RabbitMQ中,在生产者和队列之间有一个交换器模块。根据配置的路由规则,生产者发送的消息可以发送到不同的队列中。路由规则很灵活,还可以自己实现。
- RabbitMQ的客户端支持大多数的编程语言。如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等
- 由于 erlang 语言的高并发特性,性能较好,吞吐量到万级;MQ 功能比较完备,健壮、稳定、易用、跨平台;开源提供的管理界面非常棒,用起来很好用,社区活跃度高;更新频率高
缺点:
- 如果有大量消息堆积在队列中,性能会急剧下降
- RabbitMQ的性能在Kafka和RocketMQ中是最差的,每秒处理几万到几十万的消息。如果应用要求高的性能,不要选择RabbitMQ。
- RabbitMQ是Erlang开发的,功能扩展和二次开发代价很高。
- 商业版需要收费,学习成本较高
三、RocketMQ
阿里系下开源的一款分布式、队列模型的消息中间件,原名Metaq,3.0版本名称改为RocketMQ,是阿里参照kafka设计思想使用java实现的一套mq。同时将阿里系内部多款mq产品(Notify、metaq)进行整合,只维护核心功能,去除了所有其他运行时依赖,保证核心功能最简化,在此基础上配合阿里上述其他开源产品实现不同场景下mq的架构,被阿里巴巴广泛应用在订单,交易,充值,流计算,消息推送,日志流式处理,binglog 分发等场景。
具有以下特点:
- 能够保证严格的消息顺序
- 提供针对消息的过滤功能
- 提供丰富的消息拉取模式
- 高效的订阅者水平扩展能力
- 实时的消息订阅机制
- 亿级消息堆积能力
官方提供了一些不同于kafka的对比差异:
https://rocketmq.apache.org/docs/motivation/优点:
- RocketMQ 主要用于有序,事务,流计算,消息推送,日志流处理,binlog分发等场景。经过了历次的双11考验,性能,稳定性可靠性没的说。
- RocketMQ 几乎具备了消息队列应该具备的所有特性和功能。
- java 开发,阅读源代码、扩展、二次开发很方便。
- 对电商领域的响应延迟做了很多优化。在大多数情况下,响应在毫秒级。如果应用很关注响应时间,可以使用RocketMQ。
- 性能比RabbitMQ高一个数量级,每秒处理几十万的消息。
- 单机吞吐量十万级,可用性非常高,分布式架构,消息可以做到 0 丢失,MQ 功能较为完善,还是分布式的,扩展性好,支持 10 亿级别的消息堆积,不会因为堆积导致性能下降。
缺点:
- 跟周边系统的整合和兼容不是很好。
- 支持的客户端语言不多,目前是 java 及 c++,其中 c++不成熟;社区活跃度一般,没有在MQ核心中去实现 JMS 等接口,有些系统要迁移需要修改大量代码
四、Kafka
大数据的杀手锏,谈到大数据领域内的消息传输,则绕不开 Kafka,这款为大数据而生的消息中间件,以其百万级 TPS 的吞吐量名声大噪,迅速成为大数据领域的宠儿,在数据采集、传输、存储的过程中发挥着举足轻重的作用。目前已经被 LinkedIn,Uber, Twitter, Netflix 等大公司所采纳。
Apache下的一个子项目,使用scala和java实现的一个高性能分布式Pub/Sub消息队列系统,具有以下特性:
- 快速持久化:通过磁盘顺序读写与零拷贝机制,可以在O(1)的系统开销下进行消息持久化;
- 高吞吐:在一台普通的服务器上既可以达到10W/s的吞吐速率;
- 高堆积:支持topic下消费者较长时间离线,消息堆积量大;
- 完全的分布式系统:Broker、Producer、Consumer都原生自动支持分布式,依赖zookeeper自动实现复杂均衡;
- 支持Hadoop数据并行加载:对于像Hadoop的一样的日志数据和离线分析系统,但又要求实时处理的限制,这是一个可行的解决方案。
Kafka的可靠性,稳定性和功能特性基本满足大多数的应用场景。跟周边系统的兼容性是数一数二的,尤其是大数据和流计算领域,几乎所有相关的开源软件都支持Kafka。Kafka是Scala和Java开发的,对批处理和异步处理做了大量的设计,因此Kafka可以得到非常高的性能。它的异步消息的发送和接收是最好的,但是跟RocketMQ拉不开数量级,每秒处理几十万的消息。如果是异步消息,并且开启了压缩,Kafka最终可以达到每秒处理2000w消息的级别。
优点:
- 性能卓越,单机写入 TPS 约在百万条/秒,最大的优点,就是吞吐量高。时效性 ms 级可用性非常高,kafka 是分布式的,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用,消费者采用 Pull 方式获取消息, 消息有序, 通过控制能够保证所有消息被消费且仅被消费一次;有优秀的第三方KafkaWeb 管理界面 Kafka-Manager;在日志领域比较成熟,被多家公司和多个开源项目使用;功能支持: 功能较为简单,主要支持简单的 MQ 功能,在大数据领域的实时计算以及日志采集被大规模使用。
- 支持多个生产者和消费者
- 支持broker的横向拓展
- 副本集机制,实现数据冗余,保证数据不丢失
- 通过topic将数据进行分类
- 通过分批发送压缩数据的方式,减少数据传输开销,提高吞高量
- 支持多种模式的消息
- 基于磁盘实现数据的持久化
- 高性能的处理信息,在大数据的情况下,可以保证亚秒级的消息延迟
- 一个消费者可以支持多种topic的消息
- 对CPU和内存的消耗比较小
- 对网络开销也比较小
- 支持跨数据中心的数据复制
- 支持镜像集群
缺点:
- Kafka 单机超过 64 个队列/分区,Load 会发生明显的飙高现象,队列越多,load 越高,发送消息响应时间变长,使用短轮询方式,实时性取决于轮询间隔时间,消费失败不支持重试;支持消息顺序,但是一台代理宕机后,就会产生消息乱序,社区更新较慢;
- 由于是批量发送,所以数据达不到真正的实时
- 对于mqtt协议不支持
- 不支持物联网传感数据直接接入
- 只能支持统一分区内消息有序,无法实现全局消息有序
- 监控不完善,需要安装插件
- 需要配合zookeeper进行元数据管理
- 会丢失数据,并且不支持事务
- 可能会重复消费数据,消息会乱序,可用保证一个固定的partition内部的消息是有序的,但是一个topic有多个partition的话,就不能保证有序了,需要zookeeper的支持,topic一般需要人工创建,部署和维护一般都比mq高
五、ZeroMQ
号称最快的消息队列系统,专门为高吞吐量/低延迟的场景开发,在金融界的应用中经常使用,偏重于实时数据通信场景。ZMQ能够实现RabbitMQ不擅长的高级/复杂的队列,但是开发人员需要自己组合多种技术框架,开发成本高。因此ZeroMQ具有一个独特的非中间件的模式,更像一个socket library,你不需要安装和运行一个消息服务器或中间件,因为你的应用程序本身就是使用ZeroMQ API完成逻辑服务的角色。但是ZeroMQ仅提供非持久性的队列,如果down机,数据将会丢失。如:Twitter的Storm中使用ZeroMQ作为数据流的传输。
ZeroMQ套接字是与传输层无关的:ZeroMQ套接字对所有传输层协议定义了统一的API接口。默认支持 进程内(inproc) ,进程间(IPC) ,多播,TCP协议,在不同的协议之间切换只要简单的改变连接字符串的前缀。可以在任何时候以最小的代价从进程间的本地通信切换到分布式下的TCP通信。ZeroMQ在背后处理连接建立,断开和重连逻辑。
特性:
- 无锁的队列模型:对于跨线程间的交互(用户端和session)之间的数据交换通道pipe,采用无锁的队列算法CAS;在pipe的两端注册有异步事件,在读或者写消息到pipe的时,会自动触发读写事件。
- 批量处理的算法:对于批量的消息,进行了适应性的优化,可以批量的接收和发送消息。
- 多核下的线程绑定,无须CPU切换:区别于传统的多线程并发模式,信号量或者临界区,zeroMQ充分利用多核的优势,每个核绑定运行一个工作者线程,避免多线程之间的CPU切换开销。
六、主要消息中间件的比较
Kafka:Kafka 主要特点是基于Pull 的模式来处理消息消费,追求高吞吐量,一开始的目的就是用于日志收集和传输,适合产生大量数据的互联网服务的数据收集业务。大型公司建议可以选用,如果有日志采集功能,肯定是首选 kafka 了。
RocketMQ:天生为金融互联网领域而生,对于可靠性要求很高的场景,尤其是电商里面的订单扣款,以及业务削峰,在大量交易涌入时,后端可能无法及时处理的情况。RoketMQ 在稳定性上可能更值得信赖,这些业务场景在阿里双 11 已经经历了多次考验,如果你的业务有上述并发场景,建议可以选择 RocketMQ。
RabbitMQ:结合 erlang 语言本身的并发优势,性能好时效性微秒级,社区活跃度也比较高,管理界面用起来十分方便,如果你的数据量没有那么大,中小型公司优先选择功能比较完备的 RabbitMQ。
两个表格:
-
RPC常用消息中间件
2019-09-01 22:40:38一、消息中间件 消息队列技术是分布式应用间交换信息的一种技术。消息队列可驻留在内存或磁盘上,队列存储消息直到它们被应用程序读走。通过消息队列,应用程序可独立地执行–它们不需要知道彼此的位置、或在继续执行...一、消息中间件
消息队列技术是分布式应用间交换信息的一种技术。消息队列可驻留在内存或磁盘上,队列存储消息直到它们被应用程序读走。通过消息队列,应用程序可独立地执行–它们不需要知道彼此的位置、或在继续执行前不需要等待接收程序接收此消息。
总体来说,消息中间件有以下作用:降低耦合、流量消峰、异步通信、可靠性传输
1.降低耦合:通过发布订阅的方式松耦合
我们以注册业务为例,注册成功会发送短信、邮件给用户来确认,传统架构模型是这样:
邮件业务和短信业务的代码是写在用户注册的流程里,无论是通过接口的方式来实现,还是远程调用的方式来实现,耦合度都很高,现在,新增一个需求,用户注册完成以后不发送邮件了,而是给用户“增加积分”,我们来分析这几种情况:第一、都在一个业务系统内通过代码堆积、接口调用的方式来实现注册成功后的业务处理,我们需要改动注册代码,上线时需要启停应用,这种方式耦合度最高。
第二、通过远程调用的方式,当我们要新增业务处理时,还是要改动主流程代码,避免不了启停应用。
如果我们引入消息中间件,如下:
通过发布订阅的方式,用户注册成功后,给消息中间件发送一个消息,各个业务端订阅同一个频道的消息,接收到注册成功的消息后就执行相应业务。新增“增加积分”,就让积分系统相关处理订阅这个消息就够了,不用改动用户业务代码,不用启停应用,就可以实现业务的平滑扩展。2.异步通信
还拿上面举例,传统架构中当用户注册完成,并发送完短信邮件后才返回客户端通知用户注册成功。而使用消息中间件后用户提交完注册信息处理完成后即可提示用户注册成功,后续短信服务、邮件服务得到订阅的频道中的用户注册成功消息后再去发送短信和邮件,业务之间不再相互制约。
3.流量消峰、防浪涌
消息中间件可以在峰值时堆积消息,而在峰值过去后下游系统慢慢消费消息解决流量洪峰的问题。
并发量达到高峰时,后端系统压力通常会很大,无论是应用服务器还是数据库服务器,这个时候可以将类似请求放到消息中间件的消息队列中堆积起来慢慢处理,也可以设置消息队列的大小达到控制并发量的目的,商品秒杀的业务场景比较典型。4.可靠性传输
基于消息的通信是可靠的,消息不会丢失。大多数消息中间件都提供将消息持久化到磁盘的功能。开篇的第一个场景中,消息中间件可以将生产者生产的消息持久化到磁盘,后端应用宕机,但消息不会丢失,应用重启继续处理。
你可能会有这样的疑问,那消息中间件宕机了,接收不到消息怎么持久化?没关系,消息中间件提供了多种消息复制策略、持久化策略,集群部署策略等都可以保证消息的可靠性传输。
二、消息中间件模式
三、常用消息中间件
RabbitMQ
1.RabbitMQ特点:
RabbitMQ是一个由Erlang语言开发的基于AMQP标准的开源实现。RabbitMQ最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。其具体特点包括:- 可靠性
- 灵活的路由
- 支持消息集群
- 高可用性
- 支持多种协议 (除支持AMQP协议之外,还通过插件的方式支持其他消息队列协议,如STOMP、MQTT)
- 支持多语言客户端
- 提供管理界面
- 提供跟踪机制
- 提供插件机制 (RabbitMQ提供了许多插件,也可以编写自己的插件)
- 总结:
RabbitMQ最大的优势在于提供了比较灵活的消息路由策略、高可用性、可靠性以及丰富的插件、多种平台支持和完善的文档。不过,由于AMQP协议本身导致它的实现比较重量,从而使得与其他MQ (比如Kafka) 对比其吞吐量处于下风。
ActiveMQ
1.ActiveMQ 特点:
ActiveMQ是由Apache出品的一款开源消息中间件,旨在为应用程序提供高效、可扩展、稳定、安全的企业级消息通信。ActiveMQ实现了JMS 1.1 并提供了很多附加的特性,比如JMX管理、主从管理、消息组通信、消息优先级、延迟接收消息、虚拟接收者、消息持久化、消息队列监控等。主要特性如下:-
支持Java、C、C++、C#、Ruby、Perl、Python、PHP等多种语言的客户端和协议,如OpenWire、STOMP、AMQP、MQTT协议。
-
提供了像消息组通信、消息优先级、延迟接收消息、虚拟接收者、消息持久化之类的高级特性。
-
完全支持JMS 1.1 和 J2EE 1.4 规范 (包括持久化、分布式事务消息、事务)
-
支持Spring框架,ActiveMQ 可以通过Spring 的配置文件方式很容易嵌入Spring应用中。
-
通过了常见的J2EE服务器测试,比如TomEE、Geronimo、JBoss、GlassFish、WebLogic。
-
连接方式多样化,ActiveMQ 提供了多种连接方式,例如 in-VM、TCP、SSL、NIO、UDP、多播、JGroups、JXTA。
-
支持通过使用JDBC 和 Journal 实现消息的快速持久化。
-
为高性能集群、客户端-服务器、点对点通信等场景而设计。
-
提供了技术和语言中立的REST API 接口。
-
支持以AJAX 方式调用 ActiveMQ。
-
ActiveMQ 可以轻松地与CXF、Axis 等 WebService 技术整合,以提供可靠的消息传递。
-
可以作为内存中的JMS 提供者,非常适合 JMS 单元测试。
Kafka
1.Kafka 特点:
Kafka 最早是由LinkedIn 公司开发的一种分布式的基于 发布/订阅 的消息系统,后来成为 Apache 的顶级项目。其主要特点如下: -
同时为发布和订阅提供高吞吐量。(Kafka 的设计目标是以时间复杂度为 O(1) 的方式提供消息持久化能力的,即使对TB级别以上数据也能保证常数时间的访问性能,即使在非常廉价的商用机器上也能做到单机支持每秒 100K 条消息的传输)
-
消息持久化。 (将消息持久化到磁盘,因此可用于批量消费,例如 ETL 以及实时应用程序。通过将数据持久化到硬盘以及复制可以防止数据丢失。)
-
分布式。 (支持服务器间的消息分区及分布式消费,同时保证每个Partition 内的消息顺序传输。其内部的Producer、Broker 和 Consumer 都是分布式架构,这更易于向外扩展。)
-
消费消息采用 Pull 模式。(消息被处理的状态是在 Consumer 端维护的,而不是由服务器端维护,Broker 无状态,Consumer 自己保存offet。)
-
支持Online 和 Offline 场景,同时支持离线数据处理和实时数据处理。
五、RocketMQ
1.RocketMQ 特点:
RocketMQ是阿里巴巴于2012年开源的分布式消息中间件,后来捐赠给 Apache软件基金会,并于2017年9月25日成为Apache的顶级项目。作为经历过多次阿里巴巴“双11” 这种“超级工程”的洗礼并有稳定出色表现的国产中间件,以其高性能、低延迟和高可靠等特性近年来被越来越多的国内企业所使用。其主要特点如下: -
具有灵活的可扩展性。 (RocketMQ 天然支持集群,其核心四大组件(NameServer、Broker、Producer、Consumer)的每一个都可以在没有单点故障的情况下进行水平扩展。)
-
具有海量消息堆积能力。 (RocketMQ 采用零拷贝原理实现了超大量消息的堆积能力,据说单机已经可以支持亿级消息堆积,而且在堆积了这么多消息后依然保持写入低延迟)
-
支持顺序消息。 (RocketMQ 可以保证消息消费者按照消息发送的顺序对消息进行消费。顺序消息分为全局有序消息和局部有序消息,一般推荐使用局部有序消息,即生产者通过将某一类消息按顺序发送至同一个队列中来实现。)
-
支持多种消息过滤方式。 (消息过滤分为在服务器端过滤和在消费端过滤。在服务器端过滤时可以按照消息消费者的要求进行过滤,优点是减少了不必要的消息传输,缺点是增加了消息服务器的负担,实现相对复杂。消费端过滤则完全由具体应用自定义实现,这种方式更加灵活,缺点是很多无用的消息会被传输给消息消费者。)
-
支持事务消息。 (RocketMQ 除支持普通消息、顺序消息之外,还支持事务消息,这个特性对于分布式事务来说提供了另一种解决思路。)
-
支持回溯消费。 (回溯消费是指对于消费者已经消费成功的消息,由于业务需求需要重新消费。RocketMQ 支持按照时间回溯消费,时间维度精确到毫秒,可以向前回溯,也可以向后回溯。)
下一篇我们介绍一下ngnix反向代理服务器及netty框架。
-
详解消息中间件及其应用场景和常用消息中间件的技术选型(RabbitMQ、Kafka 、RocketMQ、ActiveMQ)
2021-02-19 17:14:52消息中间件简介 消息中间件的使用场景 消息中间件的产生背景、特点和常用协议 常用消息中间件介绍(RabbitMQ、Kafka 、RocketMQ、ActiveMQ) 常用消息中间件的对比 常用消息中间件,如何技术选型?文章目录
- 消息中间件简介
- 消息中间件的使用场景
- 常用消息中间件介绍
- 常用消息中间件技术对比
- 消息中间件如何选型?
- 参考文献:
消息中间件简介
常用概念
消息
消息是指软件对象之间进行交互作用和通讯利用的一种方式。
中间件
非底层操作系统软件,非业务应用软件,不是直接给最终用户使用的,不能直接给客户带来价值的软件统称为中间件
消息队列
消息队列是消息中间件的一种实现方式。
消息中间件
消息中间件是基于队列与消息传递技术,在网络环境中为应用系统提供同步或异步、可靠的消息传输的支撑性软件系统。
关注于数据的发送和接受,利用高效可靠的异步消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息排队模型,它可以在分布式环境下扩展进程间的通信。
这可能比较抽象,但消息队列是消息中间件的一种实现方式,后文我们将举出实际的场景来理解消息中间件。
消息中间件产生背景
在客户端与服务器进行通讯时.客户端调用后,必须等待服务对象完成处理返回结果才能继续执行。
这样会引发很多的问题:
-
客户与服务器对象的生命周期紧密耦合,客户进程和服务对象进程都都必须正常运行;
-
如果由于服务对象崩溃或者网络故障导致用户的请求不可达,客户会受到异常。
为了解决这样的问题,消息中间件技术应运而生。
面向消息的中间件(MessageOrlented MiddlewareMOM)较好的解决了以上问题。发送者将消息发送给消息服务器,消息服务器将消感存放在若千队列中,在合适的时候再将消息转发给接收者。
这种模式下,好处有很多:
-
发送和接收是异步的,发送者无需等待;
-
二者的生命周期未必相同: 发送消息的时候接收者不一定运行,接收消息的时候发送者也不一定运行;
-
一对多通信: 对于一个消息可以有多个接收者。
消息队列的特点
-
先进先出:消息队列的顺序在入队的时候就基本已经确定了,一般是不需人工干预的。
-
发布订阅:发布订阅是一种很高效的处理方式,如果不发生阻塞,基本可以当成是同步操作。
-
持久化:持久化确保消息队列的使用不只是一个部分场景的辅助工具,而是让消息队列能像数据库一样存储核心的数据。
-
分布式:在现在大流量、大数据的使用场景下,支持分布式的部署,才能被广泛使用。消息队列的定位就是一个高性能的中间件。
消息中间件常用协议
1) AMQP协议(Advanced Message Queuing Protocol)
AMQP是一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同开发语言等条件的限制。
优点:可靠、通用
2) MQTT协议(Message Queuing Telemetry Transport,消息队列遥测传输)
MQTT是IBM开发的一个即时通讯协议,有可能成为物联网的重要组成部分。该协议支持所有平台,几乎可以把所有联网物品和外部连接起来,被用来当做传感器和致动器(比如通过Twitter让房屋联网)的通信协议。
优点:格式简洁、占用带宽小、移动端通信、PUSH、嵌入式系统
3) STOMP协议(Streaming Text Orientated Message Protocol)
STOMP是流文本定向消息协议,是一种为MOM(Message Oriented Middleware,面向消息的中间件)设计的简单文本协议。STOMP提供一个可互操作的连接格式,允许客户端与任意STOMP消息代理(Broker)进行交互。
优点:命令模式(非topic\queue模式)
4) XMPP协议(Extensible Messaging and Presence Protocol,可扩展消息处理现场协议)
XMPP是基于可扩展标记语言(XML)的协议,多用于即时消息(IM)以及在线现场探测。适用于服务器之间的准即时操作。核心是基于XML流传输,这个协议可能最终允许因特网用户向因特网上的其他任何人发送即时消息,即使其操作系统和浏览器不同。
优点:通用公开、兼容性强、可扩展、安全性高,但XML编码格式占用带宽大
5) 其他基于TCP/IP自定义的协议
有些特殊框架(如:redis、kafka、zeroMq等)根据自身需要未严格遵循MQ规范,而是基于TCP\IP自行封装了一套协议,通过网络socket接口进行传输,实现了MQ的功能。
扩展:JMS
1.什么是JMS
JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持(百度百科给出的概述)。我们可以简单的理解:两个应用程序之间需要进行通信,我们使用一个JMS服务,进行中间的转发,通过JMS 的使用,我们可以解除两个程序之间的耦合。
2.JMS的优势
①Asynchronous(异步)
JMS is asynchronous by default. So to receive a message, the client is not required to send the request. The message will arrive automatically to the client as they become available.(JMS 原本就是一个异步的消息服务,客户端获取消息的时候,不需要主动发送请求,消息会自动发送给可用的客户端)
②Reliable(可靠)
JMS provides the facility of assurance that the message will delivered once and only once. You know that duplicate messages create problems. JMS helps you avoiding such problems.(JMS保证消息只会递送一次。大家都遇到过重复创建消息问题,而JMS能帮你避免该问题。)
3. JMS的消息模型
JMS具有两种通信模式:
①Point-to-Point Messaging Domain (点对点)
②Publish/Subscribe Messaging Domain (发布/订阅模式)
在JMS API出现之前,大部分产品使用“点对点”和“发布/订阅”中的任一方式来进行消息通讯。JMS定义了这两种消息发送模型的规范,它们相互独立。任何JMS的提供者可以实现其中的一种或两种模型,这是它们自己的选择。JMS规范提供了通用接口保证我们基于JMS API编写的程序适用于任何一种模型。
(1)Point-to-Point Messaging Domain(点对点通信模型)
在点对点通信模式中,应用程序由消息队列,发送方,接收方组成。每个消息都被发送到一个特定的队列,接收者从队列中获取消息。队列保留着消息,直到他们被消费或超时。
特点:
- 每个消息只要一个消费者
- 发送者和接收者在时间上是没有时间的约束,也就是说发送者在发送完消息之后,不管接收者有没有接受消息,都不会影响发送方发送消息到消息队列中。
- 发送方不管是否在发送消息,接收方都可以从消息队列中取到消息(The receiver can fetch message whether it is running or not when the sender sends the message)
- 接收方在接收完消息之后,需要向消息队列应答成功
(2)Publish/Subscribe Messaging Domain(发布/订阅通信模型)
在发布/订阅消息模型中,发布者发布一个消息,该消息通过topic传递给所有的客户端。该模式下,发布者与订阅者都是匿名的,即发布者与订阅者都不知道对方是谁。并且可以动态的发布与订阅Topic。Topic主要用于保存和传递消息,且会一直保存消息直到消息被传递给客户端。
特点:
- 一个消息可以传递个多个订阅者(即:一个消息可以有多个接受方)
- 发布者与订阅者具有时间约束,针对某个主题(Topic)的订阅者,它必须创建一个订阅者之后,才能消费发布者的消息,而且为了消费消息,订阅者必须保持运行的状态。
- 为了缓和这样严格的时间相关性,JMS允许订阅者创建一个可持久化的订阅。这样,即使订阅者没有被激活(运行),它也能接收到发布者的消息。
4.JMS接收消息的方式
在JMS中,消息的产生和消息的消费是异步的。对于消费来说,JMS的消息者可以通过两种方式来消费消息。
(1)同步(Synchronous)
在同步消费信息模式模式中,订阅者/接收方通过调用 receive()方法来接收消息。在receive()方法中,线程会阻塞直到消息到达或者到指定时间后消息仍未到达。
(2)异步(Asynchronous)
使用异步方式接收消息的话,消息订阅者需注册一个消息监听者,类似于事件监听器,只要消息到达,JMS服务提供者会通过调用监听器的onMessage()递送消息。
5.JMS与AMQP的区别
- JMS是定义了统一的接口,来对消息操作进行统一;AMQP是通过规定协议来统一数据交互的格式
- JMS限定了必须使用Java语言;AMQP只是协议,不规定实现方式,因此是跨语言的。
- JMS规定了两种消息模型 点对点、发布订阅;而AMQP的消息模型有7种
为什么要使用消息中间件?
以一个电商平台为例,分析为什么要使用消息中间件,以便于理解消息中间件的使用场景。
订单系统堪称是整个电商交易平台的核心,它需要与很多内部模块、外部第三方系统打交道。从下订单到支付完成这个过程中,需要完成很多额外的步骤:
- 为用户积分
- 发放红包卡券
- 库存扣减
- 通知物流系统
- 发送短信通知
- …
订单系统流程图
订单系统存在的问题
对于一个电商APP而言,每卖掉了一个商品,就要扣减掉商品的库存,而且一旦用户成功支付了,还需要将订单的状态更新成待发货。
在完成这些最核心的功能后,其实是有很多事情要做的,比如上图红色的部分。如果这些动作都以同步方式来完成,根据线上系统的一般统计,多个子步骤全部执行完毕,加起来大概需要1秒~2秒的时间。有时候在高峰期并发量特别大,服务器的磁盘、IO、CPU的负载会很高,执行SQL语句的性能也会有所下降。因此有的时候甚至需要几秒钟的时间完成上述几个步骤。
那么影响是什么呢? 想象一下,如果你是一个用户,在支付完一个订单之后,界面上会有一个圈圈不停的旋转,让你等待好几秒之后才能提示支付成功。对用户来说几秒钟的时间,会让人非常不耐烦的!
所以首先针对子步骤过多、速度过慢、让用户支付之后等待时间过长的问题,就是订单系统亟需解决的问题! 而解决这个问题的一大利器就是消息中间件,英文全称“Message Queue”,简称MQ。
引入MQ对订单系统的好处
在引入消息中间件以后,系统A和系统B之间就由同步变为异步通信,而完成这样的一个核心概念就是“消息”。
系统A发送消息给MQ后,就认为已经完成了自己的任务;然后系统B根据自己的情况,可能会在系统A投递消息到MQ之后的1秒内,也可能是1分钟之后,也可能是1小时之后,多长时间都有可能。
反正不管是多长时间后,系统B会根据自己的节奏从MQ里获取到一条属于自己的消息,再根据消息的指示完成自己的工作。 在“异步调用”的整个过程中,系统A仅仅是发个消息到MQ,至于系统B什么时候获取消息,有没有获取消息,系统A是不管的。
对于订单系统而言,在引入MQ后,我们可以让订单系统仅仅完成最核心的功能,然后发送消息到MQ。比如需要进行减库存,就发送一个消息到库存消息队列中,然后库存系统从这个MQ里获取消息再进行处理就可以,把这些很耗时的步骤慢慢执行,从而也实现了系统之间的解耦。
在双11大促活动的时候,同样可以让瞬间涌入的大量下单请求到MQ里去排队,然后让订单系统在后台慢慢的获取订单,以数据库可以接受的速率完成操作,避免瞬间请求量过大击垮数据库。
消息中间件的使用场景
1)异步处理
场景说明:提供新用户注册后,发送短信或邮件的功能
传统方式
传统的做法有有两种 1.串行方式;2.并行方式
1.串行方式
将注册信息写入数据库成功后,发送注册邮件,再发送注册短信。以上三个任务全部完成后,返回给客户端。
2.并行方式
将注册信息写入数据库成功后,发送注册邮件的同时,发送注册短信。以上三个任务完成后,返回给客户端。与串行的差别是,并行的方式可以提高处理的时间。
分析
假设三个业务节点每个使用50毫秒钟,不考虑网络等其他开销,则串行方式的时间是150毫秒,并行的时间可能是100毫秒。
因为CPU在单位时间内处理的请求数是一定的,假设CPU1秒内吞吐量是100次。则串行方式1秒内CPU可处理的请求量是7次(1000/150)。并行方式处理的请求量是10次(1000/100)。
如以上案例描述,传统的方式系统的性能(并发量,吞吐量,响应时间)会有瓶颈。
消息中间件方式
引入消息队列,将不是必须的业务逻辑,将异步处理改造后的架构如下:
分析
按照以上约定,用户的响应时间相当于是注册信息写入数据库的时间,也就是50毫秒。注册邮件,发送短信写入消息队列后,直接返回,因此写入消息队列的速度很快,基本可以忽略,因此用户的响应时间可能是50毫秒。至于从消息队列中发送邮件和短信完全可以异步处理,不受时间的限制,等邮件服务和短信服务需要的时候从消息队列中消费消息即可。
因此架构改变后,系统的吞吐量提高到每秒20 QPS。比串行提高了3倍,比并行提高了两倍。
2)应用解耦
场景说明:用户下单后,订单系统需要通知库存系统。
传统方式
传统的做法是,订单系统直接调用库存系统的接口。
传统模式的缺点:假如库存系统无法访问,则订单减库存将失败,从而导致订单失败,订单系统与库存系统耦合
消息中间件方式
引入应用消息队列后的方案:
订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功
库存系统:订阅下单的消息,采用拉/推的方式,获取下单信息,库存系统根据下单信息,进行库存操作假如:在下单时库存系统不能正常使用。也不影响正常下单,因为下单后,订单系统写入消息队列就不再关心其他的后续操作了。实现订单系统与库存系统的应用解耦
3)流量削峰
场景说明:秒杀活动,一般会因为流量过大,导致流量暴增,应用挂掉。为解决这个问题,一般需要在应用前端加入消息队列。通过加入消息队列完成如下功能:
-
可以控制活动的人数
-
可以缓解短时间内高流量压垮应用
用户的请求,服务器接收后,首先写入消息队列。假如消息队列长度超过最大数量,则直接抛弃用户请求或跳转到错误页面。秒杀业务根据消息队列中的请求信息,再做后续处理。
其他应用场景
1.解决数据丢失问题
有些情况下,处理数据的过程会失败。除非数据被持久化(但又不想给数据库过大的压力),否则将造成丢失。消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险。许多消息队列所采用的”插入-获取-删除”范式中,在把一个消息从队列中删除之前,需要你的处理系统明确的指出该消息已经被处理完毕,从而确保你的数据被安全的保存直到你使用完毕。
2.过载保护
在访问量剧增的情况下,应用仍然需要继续发挥作用,但是这样的突发流量无法提取预知;如果为了能处理这类瞬间峰值访问为标准来投入资源随时待命无疑是巨大的浪费。使用消息队列能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩溃。
3.异常恢复
系统的一部分组件失效时,不会影响到整个系统。消息队列降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。
4.缓冲
在任何重要的系统中,都会有需要不同的处理时间的元素。消息队列通过一个缓冲层来帮助任务最高效率的执行,该缓冲有助于控制和优化数据流经过系统的速度。以调节系统响应时间。
5. 数据流处理
分布式系统产生的海量数据流,如:业务日志、监控数据、用户行为等,针对这些数据流进行实时或批量采集汇总,然后进行大数据分析是当前互联网的必备技术,通过消息队列完成此类数据收集是最好的选择。
常用消息中间件介绍
当前使用较多的消息队列有RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMQ等,而部分数据库如Redis、MySQL以及phxsql也可实现消息队列的功能。
1)RabbitMQ
RabbitMQ于2007年发布,是一个在AMQP(高级消息队列协议)基础上完成的,可复用的企业消息系统,是当前最主流的消息中间件之一。
RabbitMQ是使用Erlang语言开发的开源消息队列系统,基于AMQP协议来实现。AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。AMQP协议更多用在企业系统内,对数据一致性、稳定性和可靠性要求很高的场景,对性能和吞吐量的要求还在其次。
主要特性
- 可靠性:提供了多种技术可以让你在性能和可靠性之间进行权衡。这些技术包括持久性机制、投递确认、发布者证实和高可用性机制;
- 灵活的路由:消息在到达队列前是通过交换机进行路由的。RabbitMQ为典型的路由逻辑提供了多种内置交换机类型。如果你有更复杂的路由需求,可以将这些交换机组合起来使用,你甚至可以实现自己的交换机类型,并且当做RabbitMQ的插件来使用;
- 消息集群:在相同局域网中的多个RabbitMQ服务器可以聚合在一起,作为一个独立的逻辑代理来使用;
- 队列高可用:队列可以在集群中的机器上进行镜像,以确保在硬件问题下还保证消息安全;
- 支持多种协议:支持多种消息队列协议;
- 支持多种语言:用Erlang语言编写,支持只要是你能想到的几乎所有编程语言;
- 管理界面:RabbitMQ有一个易用的用户界面,使得用户可以监控和管理消息Broker的许多方面;
- 跟踪机制:如果消息异常,RabbitMQ 提供消息跟踪机制,使用者可以找出发生了什么;
- 插件机制:提供了许多插件,来从多方面进行扩展,也可以编写自己的插件。
优点
- 由于Erlang语言的特性,消息队列性能较好,支持高并发;
- 健壮、稳定、易用、跨平台、支持多种语言、文档齐全;
- 有消息确认机制和持久化机制,可靠性高;
- 高度可定制的路由;
- 管理界面较丰富,在互联网公司也有较大规模的应用,社区活跃度高。
缺点
- 尽管结合 Erlang 语言本身的并发优势,性能较好,但是不利于做二次开发和维护;
- 实现了代理架构,意味着消息在发送到客户端之前可以在中央节点上排队。此特性使得RabbitMQ易于使用和部署,但是使得其运行速度较慢,因为中央节点 增加了延迟,消息封装后也比较大;需要学习比较复杂的接口和协议,学习和维护成本较高。
2)Kafka
Apache Kafka是LinkedIn开源的分布式发布-订阅消息系统(使用scala实现的一个高性能分布式Publish/Subscribe消息队列系统)。它最初由LinkedIn公司基于独特的设计实现为一个分布式的日志提交系统(a distributed commit log),之后成为Apache项目的一部分,目前归属于Apache顶级项目。
Kafka主要为高吞吐量的订阅发布系统而设计,追求速度与持久化。kafka中的消息由键、值、时间戳组成,kafka不记录每个消息被谁使用,只通过偏移量记录哪些消息是未读的,kafka中可以指定消费组来实现订阅发布的功能。
主要特性
- 快速持久化:可以在O(1)的系统开销下进行消息持久化;
- 高吞吐:在一台普通的服务器上既可以达到10W/s的吞吐速率;
- 高堆积:支持topic下消费者较长时间离线,消息堆积量大;
- 完全的分布式系统:Broker、Producer和Consumer都原生自动支持分布式,自动实现负载均衡;
- 支持同步和异步复制两种高可用机制;
- 支持数据批量发送和拉取;
- 零拷贝技术(zero-copy):减少IO操作步骤,提高系统吞吐量;
- 数据迁移、扩容对用户透明;
- 无需停机即可扩展机器;
- 支持Hadoop数据并行加载:对于像Hadoop的一样的日志数据和离线分析系统,但又要求实时处理的限制,这是一个可行的解决方案。
- 其他特性:丰富的消息拉取模型、高效订阅者水平扩展、实时的消息订阅、亿级的消息堆积能力、定期删除机制;
优点
- 客户端语言丰富:支持Java、.Net、PHP、Ruby、Python、Go等多种语言;
- 高性能:单机写入TPS约在100万条/秒,消息大小10个字节;
- 提供完全分布式架构,并有replica机制,拥有较高的可用性和可靠性,理论上支持消息无限堆积;
- 支持批量操作;
- 消费者采用Pull方式获取消息。消息有序,通过控制能够保证所有消息被消费且仅被消费一次;
- 有优秀的第三方KafkaWeb管理界面Kafka-Manager;
- 在日志领域比较成熟,被多家公司和多个开源项目使用。
缺点
- Kafka单机超过64个队列/分区时,Load时会发生明显的飙高现象。队列越多,负载越高,发送消息响应时间变长;
- 使用短轮询方式,实时性取决于轮询间隔时间;
- 消费失败不支持重试;
- 支持消息顺序,但是一台代理宕机后,就会产生消息乱序;
- 社区更新较慢。
3)RocketMQ
阿里系下开源的一款分布式、队列模型的消息中间件,原名Metaq,3.0版本名称改为RocketMQ,是阿里参照kafka设计思想使用java实现的一套mq。同时将阿里系内部多款mq产品(Notify、metaq)进行整合,只维护核心功能,去除了所有其他运行时依赖,保证核心功能最简化,在此基础上配合阿里上述其他开源产品实现不同场景下mq的架构,在阿里内部被广泛应用在订单,交易,充值,流计算,消息推送,日志流式处理,binglog分发等场景。
支持的客户端语言不多,目前是Java及C++,其中C++还不成熟;
主要特性
- 基于 队列模型:具有高性能、高可靠、高实时、分布式等特点;
- Producer、Consumer、队列都支持分布式;
- Producer向一些队列轮流发送消息,队列集合称为Topic。Consumer如果做广播消费,则一个Consumer实例消费这个Topic对应的所有队列;如果做集群消费,则多个Consumer 实例平均消费这个Topic对应的队列集合;
- 能够保证严格的消息顺序;
- 提供丰富的消息拉取模式;
- 高效的订阅者水平扩展能力;
- 实时的消息订阅机制;
- 亿级消息堆积 能力;
- 较少的外部依赖。
优点
- 单机支持1万以上持久化队列;
- RocketMQ的所有消息都是持久化的,先写入系统PAGECACHE,然后刷盘,可以保证内存与磁盘都有一份数据,而访问时,直接从内存读取。
- 模型简单,接口易用(JMS的接口很多场合并不太实用);
- 性能非常好,可以允许大量堆积消息在Broker中;
- 支持多种消费模式,包括集群消费、广播消费等;
- 各个环节分布式扩展设计,支持主从和高可用;
- 开发度较活跃,版本更新很快。
缺点
- 支持的 客户端语言不多,目前是Java及C++,其中C++还不成熟;
- RocketMQ社区关注度及成熟度也不及前两者;
- 没有Web管理界面,提供了一个 CLI (命令行界面) 管理工具带来查询、管理和诊断各种问题;
- 没有在MQ核心里实现JMS等接口;
4)ActiveMQ
ActiveMQ是由Apache出品,ActiveMQ是一个完全支持JMS1.1和J2EE 1.4规范的JMS Provider实现。它非常快速,支持多种语言的客户端和协议,而且可以非常容易的嵌入到企业的应用环境中,并有许多高级功能。
主要特性
- 服从JMS规范:JMS 规范提供了良好的标准和保证,包括:同步 或 异步 的消息分发,一次和仅一次的消息分发,消息接收和订阅等等。遵从JMS规范的好处在于,不论使用什么JMS实现提供者,这些基础特性都是可用的;
- 连接灵活性:ActiveMQ提供了广泛的连接协议,支持的协议有:HTTP/S,IP多播,SSL,TCP,UDP等等。对众多协议的支持让ActiveMQ拥有了很好的灵活性;
- 支持的协议种类多:OpenWire、STOMP、REST、XMPP、AMQP;
- 持久化插件和安全插件:ActiveMQ提供了多种持久化选择。而且,ActiveMQ的安全性也可以完全依据用户需求进行自定义鉴权和授权;
- 支持的客户端语言种类多:除了Java之外,还有:C/C++,.NET,Perl,PHP,Python,Ruby;
- 代理集群:多个ActiveMQ代理可以组成一个集群来提供服务;
- 异常简单的管理:ActiveMQ是以开发者思维被设计的。所以,它并不需要专门的管理员,因为它提供了简单又使用的管理特性。有很多中方法可以监控ActiveMQ不同层面的数据,包括使用在JConsole或者在ActiveMQ的WebConsole中使用JMX。通过处理JMX的告警消息,通过使用命令行脚本,甚至可以通过监控各种类型的日志。
优点
- 跨平台(JAVA编写与平台无关,ActiveMQ几乎可以运行在任何的JVM上);
- 可以用JDBC:可以将数据持久化到数据库。虽然使用JDBC会降低ActiveMQ的性能,但是数据库一直都是开发人员最熟悉的存储介质;
- 支持JMS规范:支持JMS规范提供的统一接口;
- 支持自动重连和错误重试机制;
- 有安全机制:支持基于shiro,jaas等多种安全配置机制,可以对Queue/Topic进行认证和授权;
- 监控完善:拥有完善的监控,包括WebConsole,JMX,Shell命令行,Jolokia的RESTful API;
- 界面友善:提供的WebConsole可以满足大部分情况,还有很多第三方的组件可以使用,比如hawtio;
缺点
- 社区活跃度不及RabbitMQ高;
- 根据其他用户反馈,会出莫名其妙的问题,会丢失消息;
- 目前重心放到activemq6.0产品Apollo,对5.x的维护较少;
- 不适合用于上千个队列的应用场景;
其余的消息中间件在目前并没有这四种常用,所以不做介绍和考虑。
常用消息中间件技术对比
RabbitMQ RocketMQ Kafka ActiveMQ 设计定位 可靠消息传输 非日志的可靠消息传输 实时数据处理及日志处理 可靠消息传输 所属社区/公司 Apache Alibaba开发,现已加入Apache Apache Apache 成熟度 成熟 成熟 日志领域成熟 成熟 社区活跃度 高 中 高 高 API完备性 高 高 高 高 开发语言 ErLang Java Scala Java 持久化方式 内存、文件 磁盘文件 磁盘文件 内存、文件、数据库 客户端支持语言 Python
Java
Ruby
PHP
C#
JavaScript
Go
Elixir
Objective-C
SwiftJava、C++(不成熟) C
C++
Erlang
Java
.net
per
PHP
Python
Ryby
Go
JavaScriptC
C++
C#
Delphi
Erlang
Adobe Flash
Haskell
Java
JavaScript
Perl
PHP
Pike
Pytho
Ruby部署方式 单机/集群 单机/集群 单机/集群 单机/集群 集群管理方式 独立 nameserver zookeeper 独立 可用性 高,基于主从架构实现高可用 非常高,分布式架构 非常高,分布式
一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用高,基于主从架构实现高可用 消息写入性能 较好 很好 非常好 较好 单机队列数 依赖内存 单机最高5万 单机超过64个队列或分区时负载变高 较好 单机吞吐量 万级,比 RocketMQ、Kafka 低一个数量级 10 万级,高吞吐 10 万级,高吞吐 万级,比 RocketMQ、Kafka 低一个数量级 时效性 微秒级,这是 RabbitMQ 的一大特点,延迟最低 ms 级 延迟在 ms 级以内 ms 级 事务消息 不支持 支持 不支持 支持 消息过滤 不支持 支持 不支持 不支持 消息失败重试 支持 支持 不支持 支持 消息重新消费
(消息幂等性问题)不支持 支持 支持 支持 批量发送 不支持 支持 支持 支持 消息清理 可用内存少于40%触发gc 指定文件保存时间过期删除 指定文件保存时间过期删除 指定文件保存时间过期删除
消息中间件如何选型?
消息中间件技术选型需要考虑的问题
- MQ的性能表现怎么样?
- 假如机器硬件条件相同,比如互联网公司最为常见的2G4核或者4G8核,能抗住多少QPS,每秒几千QPS或几万QPS,什么程度会到达性能瓶颈?
- 性能有多高,比如向MQ发送消息需要2毫秒还是20毫秒?
- 能够高可用吗,如果部署的一台服务器宕机了怎么办,有没有自动修复的机制?
- 可靠吗,会不会丢失数据?
- 支持线性的集群扩展吗,添加更多机器的机制复杂吗?
- 功能性满足吗,比如经常需要使用的功能:延迟消息、事务消息、消息累积、消息回溯、死信队列等等?
- 官方文档是否完整且清晰,社区活跃吗,如果遇到技术问题我们是否方便地找到解决办法?
- 在工业中是否已经被广泛使用了,已经被大公司验证过它的质量?
- 它是用什么语言写的,如果有个性化的需求,是否可以对源码进行修改?
消息中间件技术选型建议
1)综合对比
ActiveMQ
一般的业务系统要引入 MQ,最早大家都用 ActiveMQ,但是现在确实大家用的不多了,没经过大规模吞吐量场景的验证,社区也不是很活跃。
RabbitMQ
后来大家开始用 RabbitMQ,但是确实 erlang 语言阻止了大量的 Java 工程师去深入研究和掌控它,对公司而言,几乎处于不可控的状态,但是确实人家是开源的,比较稳定的支持,活跃度也高;
RocketMQ
现在确实越来越多的公司会去用 RocketMQ,确实很不错,毕竟是阿里出品,但社区可能有突然黄掉的风险(目前 RocketMQ 已捐给 Apache,但 GitHub 上的活跃度其实不算高)对自己公司技术实力有绝对自信的,推荐用 RocketMQ,否则回去老老实实用 RabbitMQ 吧,人家有活跃的开源社区,绝对不会黄。
所以中小型公司,技术实力较为一般,技术挑战不是特别高,用 RabbitMQ 是不错的选择;大型公司,基础架构研发实力较强,用 RocketMQ 是很好的选择。
Kafka
如果是大数据领域的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范。
2)从公司基础建设力量角度
- 中小型软件公司,建议选RabbitMQ,一方面,erlang语言天生具备高并发的特性,而且他的管理界面用起来十分方便。他的弊端也在这里,虽然RabbitMQ是开源的,然而国内有几个能定制化开发erlang的程序员呢?所幸,RabbitMQ的社区十分活跃,可以解决开发过程中遇到的bug,这点对于中小型公司来说十分重要。不考虑RocketMQ和kafka的原因是,一方面中小型软件公司不如互联网公司,数据量没那么大,选消息中间件,应首选功能比较完备的,所以kafka排除。不考虑RocketMQ的原因是,RocketMQ是阿里出品,如果阿里放弃维护RocketMQ,中小型公司一般抽不出人来进行RocketMQ的定制化开发,因此不推荐。
- 大型软件公司,根据具体使用在RocketMQ和kafka之间二选一。一方面,大型软件公司,具备足够的资金搭建分布式环境,也具备足够大的数据量。针对RocketMQ,大型软件公司也可以抽出人手对RocketMQ进行定制化开发,毕竟国内有能力改JAVA源码的人,还是相当多的。至于kafka,根据业务场景选择,如果有日志采集功能,肯定是首选kafka了。
3)从业务场景角度出发
- RocketMQ定位于非日志的可靠消息传输(日志场景也OK),目前RocketMQ在阿里集团被广泛应用在订单,交易,充值,流计算,消息推送,日志流式处理,binglog分发等场景。
- Kafka是LinkedIn开源的分布式发布-订阅消息系统,目前归属于Apache定级项目。Kafka主要特点是基于Pull的模式来处理消息消费,追求高吞吐量,一开始的目的就是用于日志收集和传输。0.8版本开始支持复制,不支持事务,对消息的重复、丢失、错误没有严格要求,适合产生大量数据的互联网服务的数据收集业务。
- RabbitMQ是使用Erlang语言开发的开源消息队列系统,基于AMQP协议来实现。AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。AMQP协议更多用在企业系统内,对数据一致性、稳定性和可靠性要求很高的场景,对性能和吞吐量的要求还在其次。
参考文献:
-
四种常用消息中间件比较分析(RabbitMQ、ActiveMQ、Kafka、RocketMQ)
2019-03-01 17:43:50一、 消息队列 1. 分布式应用与集群的区别: 如果是一个业务被拆分成多个子业务部署在不同的服务器上,那就是分布式应用;如果是同一个业务部署在多台服务器上,那就是集群。 2. 系统间通信方式: ... -
[消息中间件]几种常用的消息中间件对比
2019-05-24 15:44:55本文将从,Kafka、RabbitMQ、ZeroMQ、RocketMQ、ActiveMQ 17 个方面综合对比作为消息队列使用时的差异。 # 资料文档 Kafka:中。有kafka作者自己写的书,网上资料也有一些。 rabbitmq:多。有一些不错的书,... -
分布式消息中间件-Rocketmq
2021-01-27 14:08:38本文来自于csdn,文章分享了分布式消息中间件,主要基于JMS规范、Rocketmq的介绍、部署方式、特性的一些使用几大模块阐述。 今天要给大家分享的是分布式消息中间件。消息中间件主要是实现分布式系统中解耦、异步消息... -
常见消息中间件大 PK
2021-12-13 17:08:53文章目录1. 几种协议1.1 JMS1.1.1 JMS 介绍1.1.2 JMS 模型1.1.3 JMS 实现1.2 AMQP1.2.1 AMQP 简介1.2.2 AMQP ...说到消息中间件,估计大伙多多少少都能讲出来一些,ActiveMQ、RabbitMQ、RocketMQ、Kafka 等等各种以及 -
常见的几种消息中间件
2020-05-15 14:41:20当今市面上有很多主流的消息中间件,如老牌的ActiveMQ、RabbitMQ,炙手可热的Kafka,阿里巴巴自主开发RocketMQ等。 1、消息中间件的组成 1.1 Broker 消息服务器,作为server提供消息核心服务1.2 Producer 消息生产... -
JAVA面试系列(二)消息中间件
2022-02-11 13:44:38本人目前项目中有用到rocketMQ作为数据传输过程中的中间件,今天整理了一下资料,记录一下自己对消息中间件的理解。 一.概念 1.MQ message queue消息队列,消息队列是就是队列,是一种先进先出的数据结构。把要... -
基于消息中间件及MongoDB的物联网应用服务平台
2021-05-06 12:37:32本文依托于智能燃气数据管理系统,针对其物联网平台架构中应用服务平台在大规模设备接入场景下的性能瓶颈,提出一种结合消息中间件Kafka与NoSQL数据库MongoDB的混合方案.根据燃气公司和设备厂商的应用背景实现该方案... -
消息中间件架构讨论
2021-02-25 14:11:59接上一篇的《业务方对消息中间件的需求》,在可用性和可靠性的基础上,讨论各种架构的优缺点,最后给出自己关于消息中间件的架构思考。首先还是来看Kafka的系统架构(做消息中间件逃不开要去了解Kafka)。... -
消息中间件理解与作用
2018-06-11 14:32:27通过阅读文档大家可以很好的理解消息中间件的作用、应用模式和在互联网的使用场景 -
消息中间件概念与常用中间件选型
2021-11-22 21:15:42缺点:消息中间件存在一些瓶颈和一致性问题,对于开发来讲不直观且不易调试,有额外成本。 消息中间件概念 消息中间件就是在通信的上下游之间截断:break it,Broker 然后利用中间件解耦、异步的特性,构建弹性、... -
消息中间件书籍
2018-11-15 08:33:59收集消息中间件相关书籍,RabbitMQ实战高效部署分布式消息队列以及RabbitMQ实战指南还有kafka。 -
java消息中间件的使用与简介
2021-02-26 10:12:57一、为什么要使用消息中间件消息中间件就是可以省去繁琐的步骤,直达目的,怎么讲呢,就是比如你想很多人,知道你的动态,而知道的人可能手机没电,可能手机信号不好,可能手机不在服务区,或者看的人比较忙,看的... -
消息中间件NSQ深入与实践
2021-02-25 10:33:29最近在研究一些消息中间件,常用的MQ如RabbitMQ,ActiveMQ,Kafka等。NSQ是一个基于Go语言的分布式实时消息平台,它基于MIT开源协议发布,由bitly公司开源出来的一款简单易用的消息中间件。官方和第三方还为NSQ开发了... -
下一代消息中间件--pulsar
2018-10-20 19:09:35Apache Pulsar是一个企业级的分布式消息系统,最初由Yahoo开发并在2016年开源,目前正在Apache基金会下孵化。Plusar已经在Yahoo的生产环境使用了三年多,主要服务于Mail、Finance、Sports、 Flickr、 the Gemini Ads... -
各大主流消息中间件
2020-08-25 15:32:03在了解消息中间件之前,首先了解两个基本概念Message和Queue。 Message :消息“消息”是在两台计算机间传送的数据单位。消息可以非常简单,例如只包含文本字符串;也可以更复杂,可能包含嵌入对象。 Queue:消息... -
《分布式消息中间件实践 》_倪炜.zip
2019-06-01 15:12:30分布式消息中间件实践; 无需密码。谢谢支持 -
常用的几种消息队列中间件对比
2020-06-19 18:12:12当前使用较多的消息队列有RabbitMQ、RocketMQ、ActiveMQ...RabbitMQ于2007年发布,是一个在AMQP(高级消息队列协议)基础上完成的,可复用的企业消息系统,是当前最主流的消息中间件之一。 主要特性 可靠性:提供了多种 -
尚硅谷_消息中间件RabbitMQ_课件.docx
2021-11-07 01:39:02尚硅谷_消息中间件RabbitMQ_课件 -
消息中间件实例项目
2018-07-09 14:23:04activemq实现,提供消费方和消费方简单实例代码,分为点对点,发布订阅(发布订阅分为持久化和非持久化,非持久化需要消费方在线才可以收到消息。持久化,消费方如果没有在线,上线之后可以接收到消息) -
springboot使用消息中间件
2020-08-25 12:43:34主要介绍了springboot使用消息中间件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 -
Java消息中间件(入门篇)
2018-05-06 10:27:55为什么需要使用消息中间件通过服务调用让其他系统感知事件发生通过消息中间件解耦服务调用消息中间件带来的好处解耦:比如登录系统和日志系统它们之间通过消息中间件完成解开耦合,它们自己在后端异步得执行。... -
几种常见的消息中间件对比
2019-02-20 10:18:00RabbitMQ于2007年发布,是一个在AMQP(高级消息队列协议)基础上完成的,可复用的企业消息系统,是当前最主流的消息中间件之一。 主要特性 可靠性:提供了多种技术可以让你在性能和可靠性之间进行权衡。这些... -
从 0 开始带你成为消息中间件实战高手.zip
2020-12-21 00:17:00从 0 开始带你成为消息中间件实战高手.zip -
RabbitMQ 消息中间件
2021-01-09 13:21:46RabbitMQ 消息中间件 1、消息中间件 1、简介 消息中间件也可以称消息队列,基于数据通信来进行分布式系统的集成。 当下主流的消息中间件有RabbitMQ、Kafka、ActiveMQ、RocketMQ等。 2、作用 1、消息中间件主要作用 ... -
消息中间件简介
2021-06-15 21:12:18消息中间件(MQ)的定义 其实并没有标准定义,一般认为,消息中间件属于分布式系统中一个子系统,关注于数据的发送和接收,利用高效可靠的异步消息传递机制对分布 式系统中的其余各个子系统进行集成。 几个关键词: ...