随着互联网时代用户规模的爆发式增长,互联网应用面临着同时服务上亿用户的挑战,传统的单体架构已经无法满足互联网应用的需求,飞速增长的业务需要更加先进的技术进行支持,分布式架构成为了当前应用开发的主流架构。分布式架构将硬件和软件部署在大量不同的服务器设备上,通过消息来进行彼此之间的通信和协调,以保证规模庞大的用户使用体验。消息队列是一种系统间相互协作的通信机制,在实际工作中被用来进行系统间数据的交换,是分布式系统中的核心组件。
当前消息队列已经在企业中广泛应用,大型企业自主研发了适应其业务场景的消息队列,并以开源的形式对外输出,典型的有阿里巴巴开源的RocketMQ、Linkedin开源的Kafka、Yahoo开源的Pulsar等。开源打破了消息队列的技术垄断,为企业提供了一个共同制定事实标准的机会[1],同时开源的兴起极大地推动了云计算的发展。在当前应用上云的时代,为了更好地服务企业分布式应用的开发,国内头部云计算厂商也基于开源的消息队列推出了各自的消息队列云服务,如阿里云消息队列RocketMQ、LinkedIn消息队列Kafka、华为云消息队列Kafka、腾讯云消息队列CKafka等。面对不同的消息队列云服务,本文尝试从功能和性能两方面出发,研究其特征指标,并给出选型建议,给用户提供客观准确的参考,从而推动消息队列云服务市场的积极发展。
RocketMQ[2]是阿里巴巴研发的一款低延迟、高可靠、可伸缩、易于使用的消息中间件。RocketMQ由阿里巴巴贡献给了Apache基金会并于2017年成为顶级开源项目。RocketMQ由Java 语言开发,采用发布—订阅模式传递消息,具有高效灵活的水平扩展能力和海量消息堆积能力,近年来逐渐获得国内外企业的认可。
RocketMQ的典型特点是:在收到消息后,会将消息持久化到文件,并利用Linux文件系统内存来提高性能;支持集群部署,可在核心组件没有单点故障的情况下进行水平扩展;利用零拷贝原理解决消息堆积问题,可实现超大的消息的堆积;支持按照既定的过滤规则为下游用户提供指定类别的消息,可采用服务器端过滤,也可采用客户端过滤;支持多种消息,包括普通消息、顺序消息以及事务消息;支持按照时间或者消费位点回调之前消费过的信息。
Kafka是由LinkedIn公司开发的一个高吞吐量的分布式消息系统,开发它的目标是为处理实时数据提供一个统一、高通量、低等待的平台[3]。Kafka最大的特性就是可以实时地处理大量数据以满足各种需求场景。Kafka由Scala语言开发,其客户端在主流的编程语言里面都有对应的支持,如Scala、C++、Python、Java、GO、php等。Kafka由LinkedIn于2010年贡献给了Apache基金会并成为顶级开源项目。
Kafka的典型特点是:支持多个生产者,无论客户端在使用单个主题还是多个主题,适合用来从多个前端系统收集数据,并以统一的格式对外提供数据;支持多客户端从某个消息流上读取数据,而且消费者之间互不影响。此外,多个消费者可以组成一个群组,它们共享一个消息流,并保证整个群组对每个给定的消息只处理一次;使用一个常数级复杂度的磁盘结构来存储数据,处理TB级别数据时也能保持较高性能;通过高效地扩展Broker来保证Kafka在处理巨大的信息流数据时的低延时[4]。
Pulsar[5]是由Yahoo开发的Pub-Sub模式[6]的分布式消息平台,在 2016年开源,并于2018年9月毕业成为Apache基金会的顶级项目。其拥有灵活的消息模型和直观的客户端API,是一种用于服务器到服务器消息传递的多租户高性能解决方案[7]。
Apache Pulsar的典型特点是:能够被高效地扩容到成百上千个节点以支持每秒数百万消息的生产、传递、接收;通过BookKeeper来存储消息,保证消息不会丢失;支持将持久化的消息在多个集群间备份的能力,用户只需配置好可用区,消息就会被源源不断地复制到其他可用区;支持多种消费模式,包括独占模式(Exclusive)、共享模式(Shared)、失败转移消费模式(Failover)。
RabbitMQ[8]是一个基于高级消息队列协议[9]实现的消息系统,其服务器端用Erlang语言编写,支持多种客户端,如Python、.NET、PHP、Java、JMS等。RabbitMQ在易用性、扩展性、高可用性等方面表现优良。
RabbitMQ的典型特点是:支持几乎所有的编程语言,还支持STOMP[10]、MQTT[11]等多种协议;通过队列持久化、交换机持久化、消息持久化及ACK回应等机制保证可靠性;提供可视化的管理界面来直观地查看RabbitMQ的状态及运行情况;多个RabbitMQ节点可以组成一个集群,消息队列可以在集群中的机器上设置镜像,使得在部分节点出现问题的情况下消息队仍然可用。
加速兴起的开源技术与蓬勃发展的云计算相互促进,在开源技术的推动支持下,云计算实现了更加丰富灵活的资源调配。随着开源的消息队列产品日臻成熟,消息队列也逐渐迁移到云上,以云的形式对用户提供服务。本章将从平台安全、运维支撑、功能丰富度3个维度考察消息队列云服务。
随着云计算服务的日益繁荣,用户对云上的安全需求也愈发迫切,平台安全成了云服务提供商的首要责任。在用户使用消息队列云服务期间,云服务商除了保障网络安全、负载主机安全之外,还应针对特定服务提供对应的安全策略,可从3个方面衡量消息队列云服务的安全能力:一是身份认证,客户端与服务端连接时进行身份认证,实现对客户端的操作进行权限控制,包括对消息或集群操作的权限控制;二是数据加密,通过在消息层、网络传输层提供加密功能对重要或者敏感数据进行加密处理来保证消息数据的安全性。提供云上数据的加解密功能,支持弹性扩展以满足不同加密算法对性能的要求;三是命名空间,云服务商给租户预留合适的存储空间,应用授权和认证机制,通过命名空间对存储配额、流控、消息过期策略进行控制。
用户在使用消息队列云服务时应避免大量繁杂的部署运维工作,从而专注于自身业务逻辑的开发。这就要求云服务商在提供消息队列云服务的同时,提供相应的运维支撑能力,包括快捷高效部署使用消息队列、按需动态扩缩容量、实时监控使用状态,以保证用户业务持续稳定的运行,具体可参考的指标有5个:一是容器化支持,容器化的部署及编排增加了服务的灵活性和可用性,便于高效部署使用消息队列;二是弹性伸缩,根据消息队列的负载情况动态地增减集群机器,实现资源水平扩展与伸缩,并且支持节点负载的均衡;三是监控告警,支持用户配置报警规则,提供多种维度的告警,以提高线上运维效率;四是高可用性,具备服务容错能力,使系统在出现问题时可在指定时间内实现平滑的容错处理,具备多种容错、限流测试能力;五是日志管理,记录消息队列运行过程中生成的日志文件,包括运行信息、传输的数据包和文件信息、系统错误等,对于系统的运行进行监控,对日志进行实时采集、分析、展示等操作。
消息队列的功能维度描述了为上层分布式应用提供数据交换通道的功能丰富性,决定了能否满足用户实际业务场景需求。可从以下几个功能纬度考量消息队列云服务的完备性。
(1)多语言支持:消息队列云服务应提供开发人员基于消息队列开发应用系统的接口,支持多语言客户端,如C/C++、.NET、JAVA、Go、Python、PHP等。
(2)消息自定义:消息队列云服务应提供消息自定义属性的功能,允许用户根据业务的需要和属性规则设定自定义消息。自定义消息可以接收和应用制定的自定义属性及属性值相匹配的消息,可在接收消息时用于过滤消息。
(3)消息顺序性:消息队列云服务应提供一种严格按照顺序来发布和消费的消息,即对于指定的消息,生产者按照一定的顺序发布,消费者按照既定的先后顺序订阅。一般消息队列云服务应支持局部和全局顺序消息。
(4)延迟队列:在用户将消息发送到消息服务器时,可以为每条消息设置不同的延迟时间,在提前设定的时间点或者延迟一定时间后投递到消费者。
(5)死信队列:死信队列用于存放由于某些原因无法被及时消费的消息,消息队列云服务应支持死信队列来保证信息不会丢失。
(6)重试队列:消息队列云服务为防止消息丢失而配置特定的延迟策略,在消费端消费消息失败时会尝试重新投递该消息。
(7)消息回溯:消息队列跳过某些过期消息或者已经消费过某些消息之后,还可以通过时间或者消费位点回调消费之前的消息。
(8)消息堆积:当发送者的速度大于消费者消费的速度时,将消息大量存储在内存或者磁盘里,常用于数据削峰填谷场景。
(9)事务消息:当应用的本地操作与消息发送,或者消息生产者发送消息和消息消费者接受消息包含在一个事务里时,操作同时成功或者同时失败。失败的消息发送操作会被定时补发,以期望达到最终一致性。而失败的消息接收操作会将消息回到消息队列中,等待下次处理。
(10)优先级队列:为消息设定不同的优先级,消息按照优先级从高到低被消费。
(11)消息追踪:用于对发送或者消费完的消息进行链路追踪服务,可以查看跟踪消息的全生命周期信息,包括消息的生产时间、投递时间、服务端处理耗时投递次数、投递失败原因等信息,进而可以进行问题的快速定位与排查。
当前市场上消息队列的云服务产品质量参差不齐,作为分布式应用的关键支撑组件,考量其在不同应用场景下消息队列的性能和效率至关重要。由于不同厂商之间的消息队列实现方式不同,市场上尚未有完全统一的性能测评方法。Linux基金会下的OpenMessaging[12]项目尝试为消息传递和流技术提供与供应商无关的标准接口与测试基准,该项目包括了一个开放可扩展的性能测试框架,并提供了第三方性能基准测试脚本,目前仅支持RocketMQ、Kafka、Pulsar等开源消息产品的性能测试。总体来看,可以从3个指标着手设计性能测试方案:一是吞吐量,吞吐量指在指定并发数和消息大小的前提下,服务端单位时间内处理的消息数量。应在指定队列数、并发数和资源数前提下,测试分布式消息队列在不同场景下的吞吐量;二是时延,时延分为端到端时延和响应时延,端到端时延指的是从生产者发送信息到消费者接收信息的时间,响应时延指的是从用户发起请求到从服务器返回响应整个过程消耗的时间。在消息队列中,主要通过对比消息生产与接收时的时间戳来计算时延。可在指定队列数、并发数和资源数前提下,测试分布式消息队列的请求响应时延,如消息的生产时延、消息的消费时延、端到端的时延;三是集群加速比,主要考察分布式消息队列服务部署在大规模集群上时,云服务对于分布式调度及集群协作的优化能力。通过对同样场景的测试任务,观察其增加资源后性能指标的加速情况,计算性能增速和资源增速之间的比值。
消息队列是实现高性能、高可用、高伸缩性和最终一致性的分布式应用架构关键组件,在当前企业级应用开发中占据重要地位。消息队列云服务的推出极大地减少了企业部署应用消息队列的难度,降低了运维成本,提高了开发效率。需要提出的是,由于缺乏权威统一的行业标准,厂商之间的消息中间件互不兼容,造成了用户消息队列服务低效、混乱以及供应商锁定等问题。在开源技术与云计算的加持下,未来消息队列架构应设计为面向云计算及混合云架构,实现多云平台无缝迁移,为金融、电子商务、IoT及大数据领域提供更好的支持。
参考文献
[1] 中国信息通信研究院. 云计算发展白皮书[R/OL].(2019-07-02) [2020-04-15]. http://www.caict.ac.cn/kxyj/qwfb/bps/index_3.htm.
[2] 郭嘉凯. RocketMQ:从阿里巴巴走向世界[J]. 软件和集成电路, 2018(11):56-60.
[3] Garg N. Apache Kafka [M]. Packt Publishing Ltd, 2013.
[4] Kreps J, Narkhede N, Rao J. Kafka:A distributed messaging system for log processing[C]//Proceedings of the NetDB, 2011,11:1-7.
[5] Apache Pulsar. Pulsar 2.0 [R/OL]. [2020-04-15].http://pulsar. apache.org/docs/en/pulsar-2.0/.
[6] Fidler E, Jacobsen H A, Li G, et al. Publish/subscribe system[J]. Feature Interactions in Telecommunications and Software Systems VIII, 2005:12.
[7] Patiniotakis I, Verginadis Y, Mentzas G. PuLSaR:Preference-based cloud service selection for cloud service brokers[J]. Journal of Internet Services and Applications,2015, 6(1):1-14.
[8] Dossot D. RabbitMQ essentials[M]. Packt Publishing Ltd, 2014.
[9] Kramer J. Advanced Message Queuing Protocol (AMQP)[J]. Linux Journal, 2009, 2009(187): 3.
[10] STOMP, Stomp: The simple text oriented messaging protocol[R/ OL]. (2012-10-22)[2020-04-15]. http://stomp.github.com/ .
[11] Tantitharanukul N, Osathanunkul K, Hantrakul K, et al.MQTT-topics management system for sharing of open data [C]//2017 International Conference on Digital Arts, Media and Technology (ICDAMT). IEEE, 2017:62-65.
[12] OpenMessaging. THE openmessaging benchmark framework[R/OL]. [2020-04-15]. http://openmessaging.cloud/docs/benchmarks/.
中国信息通信研究院云计算与大数据研究所云计算部工程师,主要从事云原生中间件技术相关的研究工作。
中国信息通信研究院云计算与大数据研究所云计算部副主任,工程师,主要从事云计算领域关键技术的研究工作。
中国信息通信研究院云计算与大数据研究所云计算部工程师,主要从事容器技术的研究与标准制定工作。
北京邮电大学泛网无线通信教育部重点实验室硕士研究生。
论文引用格式:
郑立,陈屹力,刘如明,等. 基于开源的消息队列云服务研究[J]. 信息通信技术与政策, 2020(5):52-56.