1概述
1.1 基于MQ应用的技术分析
随着企业信息化建设的不断深入。多种业务应用相互关联,容易造成底层数据分散,应用系统间的耦合度高。针对该问题应从总体上调整眼下系统架构。面向不同业务应用提供统一的数据访问服务,使用消息中间件对不同系统间的交互进行解耦.
消息中间件技术有两个核心功能:异步和解耦。这两个核心功能总体上提高了应用系统的工作效率,增强了系统的可用性、稳定性和可扩展性。提升了用户体验。
消息队列已经逐渐成为企业IT系统内部通信的核心手段。当今市面上有很多主流的消息中间件,如老牌的ActiveMQ、RabbitMQ,炙手可热的Kafka,阿里巴巴自主开发RocketMQ等。它可以在分布式环境下提供应用解耦、弹性伸缩、冗余存储、流量削峰、异步通信、数据同步等等功能。
2 消息中间件主流技术框架
2.1ActiveMQ
ActiveMQ中间件是apache公司的开源子项目,使用Java完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现,少量代码就可以高效地实现高级应用场景。可插拔的传输协议支持,比如:in-VM, TCP, SSL, NIO, UDP, multicast, JGroups and JXTA transports。RabbitMQ、ZeroMQ、ActiveMQ均支持常用的多种语言客户端 C++、Java、.Net,、Python、 Php、 Ruby等。
ActiveMQ的集群方式主要有两种:Master-Slave和Broker Cluster。但在使用的过程中会发现很多的缺点。
Master-Slave方式中,只能是Master提供服务,Slave是实时地备份Master的数据,以保证消息的可靠性。当Master失效时,Slave会自动升级为Master,客户端会自动连接到Slave上工作。
Broker Cluster主要是通过network of Brokers在多个ActiveMQ实例之间进行消息的路由。
Master-Slave模式不支持负载均衡,但可以通过消息的实时备份或共享保证消息服务的可靠性
Broker Cluster模式支持负载均衡,可以提高消息的消费能力,但不能保证消息的可靠性。
所以为了支持负载均衡,同时又保证消息的可靠性,我们可以采用Msater-Slave+Broker Cluster的模式。这样一来的话,就会增加集群环境配置的复杂度,如延迟机制的设置、消息丢失、重复、迁移、消息堆积的处理,出现问题后,排查难度大。
优点:
(1)是一个快速的开源消息组件(框架),支持集群,同等网络,自动检测,TCP,SSL,广播,持久化,XA,和J2EE1.4容器无缝结合,并且支持轻量级容器和大多数跨语言客户端上的Java虚拟机。
(2)消息异步接受,减少软件多系统集成的耦合度。消息可靠接收,确保消息在中间件可靠保存,多个消息也可以组成原子事务。
(3)可以为C/C++、.NET、Perl、PHP、Python、Ruby 和一些其它语言提供客户端。在你考虑如何集成不同平台不同语言编写应用的时候,ActiveMQ 拥有巨大优势。多种客户端API可以通过ActiveMQ 发送和接受消息。
缺点:
(1)由于历史悠久,历史包袱较多,版本更新很缓慢。社区不太活跃,集群模式需要依赖Zookeeper作为注册中心实现,增加其它因素的风险。
(2)ActiveMQ默认的配置性能偏低,需要优化配置,但是配置文件复杂,ActiveMQ本身不提供管理工具,示例代码少。
(3)主页上的文档看上去比较全面,但是缺乏一种有效的组织方式,文档只有片段,用户很难由浅入深进行了解。
2.2RabbitMQ
RabbitMQ是使用Erlang语言开发的开源消息队列系统,基于AMQP协议来实现。AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。AMQP协议更多用在企业系统内,对数据一致性、稳定性和可靠性要求很高的场景,对性能和吞吐量的要求还在其次。
RabbitMQ是发家于金融行业,是一种典型的点对点模式,但可以通过设置交换器类型来实现发布订阅模式而达到广播消费的效果。RabbitMQ是AMQP协议领先的一个实现,它实现了代理(Broker)架构,意味着消息在发送到客户端之前可以在中央节点上排队。此特性使得RabbitMQ易于使用和部署,适宜于很多场景,如路由、负载均衡或消息持久化等,用消息队列只需几行代码即可搞定。但是,这使得它的可扩展性差,速度较慢,因为中央节点增加了延迟,消息封装后也比较大。
优点:
(1)数据一致性、稳定性和可靠性很高。
(2)天然支持高并发高可用。
缺点:
(1)性能和吞吐量较低。
(2)可扩展性差,速度较慢。
2.3Kafka
Kafka是LinkedIn开源的分布式发布-订阅消息系统,目前归属于Apache顶级项目。Kafka主要特点是基于Pull的模式来处理消息消费,追求高吞吐量,一开始的目的就是用于日志收集和传输。0.8版本开始支持复制,不支持事务,对消息的重复、丢失、错误没有严格要求,适合产生大量数据的互联网服务应用的数据收集业务。
它提供了类似于JMS的特性,但是在设计实现上完全不同,此外它并不是JMS规范的实现。kafka对消息保存时根据Topic进行归类,发送消息者成为Producer,消息接受者成为Consumer,此外kafka集群有多个kafka实例组成,每个实例(server)成为broker。无论是kafka集群,还是producer和consumer都依赖于zookeeper来保证系统可用性集群保存一些meta信息。
kafka的设计初衷是希望作为一个统一的信息收集平台,能够实时的收集反馈信息,并需要能够支撑较大的数据量,且具备良好的容错能力。它是一种典型的磁盘式堆积,所有的消息都存储在磁盘中。一般来说,磁盘的容量会比内存的容量要大得多,对于磁盘式的堆积其堆积能力就是整个磁盘的大小。从另外一个角度讲,消息堆积也为消息中间件提供了冗余存储的功能。
优点:
(1)持久性、可靠性:消息被持久化到本地磁盘,并且支持数据备份防止数据丢失。
(2)高吞吐量、低延迟:kafka每秒可以处理几十万条消息,它的延迟最低只有几毫秒,采用顺序写磁盘的方式,该种方式比随机写内存的效率要高,从而保证了kafka的吞吐率。
(3)可扩展性:kafka集群支持热扩展。
(4)容错性:允许集群中节点失败(若副本数量为n,则允许n-1个节点失败)。
(5)高并发:支持数千个客户端同时读写。
缺点:
(1)重复消息,kafka保证每条消息至少发送一次,虽然几率很小,但一条消息可能会被送达多次。
(2)消息乱序,Kafka某一个固定的Partition内部的消息是保证有序的,如果一个Topic有多个Partition,partition之间的消息送达不能保证有序。
(3)复杂性。Kafka需要Zookeeper的支持,Topic一般需要人工创建,部署和维护比一般MQ成本更高。
2.4RocketMQ
RocketMQ是阿里开源的消息中间件,目前归属于Apache顶级项目。它是纯Java开发,具有高吞吐量、高可用性、适合大规模分布式系统应用的特点。
RocketMQ的设计思路起源于Kafka,但并不是Kafka的一个Copy,它对消息的可靠传输及事务性做了优化,目前在阿里集团被广泛应用于交易、充值、流计算、消息推送、日志流式处理、binglog分发等场景。作为经历过多次阿里巴巴双十一这种“超级工程”的洗礼并有稳定出色表现的国产中间件,以其高性能、低延时和高可靠等特性近年来已经也被越来越多的国内企业使用。
RocketMQ 天然支持集群,其核心四组件(Name Server、Broker、Producer、Consumer)每一个都可以在没有单点故障的情况下进行水平扩展。是一个队列模型的消息中间件,具有高性能、高可靠、高实时、分布式特点。
RocketMQ 采用零拷贝原理实现超大的消息的堆积能力,单机已可以支持亿级消息堆积,而且在堆积了这么多消息后依然保持写入低延迟。可以保证消息消费者按照消息发送的顺序对消息进行消费。顺序消息分为全局有序和局部有序,一般推荐使用局部有序,即生产者通过将某一类消息按顺序发送至同一个队列来实现。
消息过滤分为在服务器端过滤和在消费端过滤。服务器端过滤时可以按照消息消费者的要求做过滤,优点是减少不必要消息传输,缺点是增加了消息服务器的负担,实现相对复杂。消费端过滤则完全由具体应用自定义实现,这种方式更加灵活,缺点是很多无用的消息会传输给消息消费者。
RocketMQ 除了支持普通消息,顺序消息之外还支持事务消息,这个特性对于分布式事务来说提供了又一种解决思路。由于业务上需求需要重新消费,RocketMQ 支持按照时间回溯消费,回溯消费是指消费者已经消费成功的消息,时间维度精确到毫秒,可以向前回溯,也可以向后回溯,而这些机制的使用只需要去修改RocketMQ 的配置文件即可实现,学习起来方便快捷。
优点:
(1)RocketMQ是站在巨人的肩膀上(kafka),对其进行了优化,是纯Java语言开发且开源,对我们更深入的学习有利。
(2)RocketMQ支持异步实时刷盘,同步刷盘,同步复制,异步复制,修改配置文件便可实现,且互不影响,在集群应用启动时指定对应的配置文件即可。
(3)RocketMQ单机支持最高5万个队列,负载不会发生明显变化,消费者的集群规模和队列数成正比,队列越多,消费类集群可以越大。
(4)RocketMQ消费失败支持定时重试,每次重试间隔时间顺延。4.3的版本开始支持分布式事物处理。
缺点:
(1)消息过滤功能扩展比较单一,会增加服务端的压力,实现也较为复杂,很多无用的消息也会发送到消息消费端。
(2)消息重复问题,它不能保证不重复,只能保证在正常情况下不重复。
(3)RocketMQ 目前只支持 Java、C++、Go 三种语言访问。
2.5对比选型
通过前面4节对几个主流消息中间件的介绍与分析,基本可以看出其相互间的优劣,而对于应用管理系统选择的消息中间件,一般重点关注性能、开发效率、安全性、配置复杂度、易用性等方面,下面通过表格对几个主流消息中间件进行对比分析:
技术框架 | RabbitMQ | RocketMQ | Kafka | ActiveMQ |
---|---|---|---|---|
事务 | 不支持 | 支持 | 不支持 | 支持 |
可用性 | 高(主从) | 非常高(分布式) | 非常高(分布式) | 高(主从) |
负载均衡 | 支持 | 支持 | 支持 | 支持 |
动态扩展 | 不支持 | 支持 | 支持 | 支持 |
可靠性 | 高可靠(基于AMQP) | 高可靠 | 非高可靠 | 非高可靠 |
重复消息过滤 | 支持 | 支持 | 不支持 | 支持 |
消息丢失 | 低 | 理论上不会丢失 | 理论上不会丢失 | 低 |
商业支持 | 无 | 阿里云 | 无 | 无 |
性能 | 高 | 优异 | 优异 | 较高 |
部署方式 | 独立 | 独立 | 独立、嵌入 | 独立、嵌入 |
特点 | Erlang语言开发,并发能力强,性能好,集群不支持动态扩展。 | 各个环节分布式扩展性设计好,主从HA,支持上万个队列和多种消费模式,性能优异,经受了淘宝双11的考验,稳定性有保障。 | 未实现JMS规范,是一套非标准的消息规范。在日志收集和大数据流处理领域表现突出。 | 功能齐全,被大量开源项目使用 |
部署方式 | 独立 | 独立 | 独立、嵌入 | 独立、嵌入 |
3 选型方案总结
通过上述章节对各个层面主流消息中间件技术框架的对比分析,对于以java技术为主的公司应用消息中间件技术框架选型总结如下:
建议选用RocketMQ消息中间件,它是纯Java开发,具有高吞吐量、高可用性、适合大规模分布式系统应用的特点,经受了淘宝双11的考验,稳定性有保障。除了阿里内部使用外,目前正在被越来越多的公司使用,如滴滴出行等国内至少有上百家单位、科研教育机构在使用,官网社区活跃度高,遇到问题可查阅的资料比较齐全。在邮政集团公司也得到了广泛的应用,如新一代寄递、在线业务平台。上手容易,可快速切换集群搭建模式,只需在启动服务时指定配置文件,且互不影响。