专访阿里云RocketMQ团队:现代微服务架构需要新的消息系统

百家 作者:InfoQ 2022-07-29 13:54:03

采访嘉宾 | 林清山、周新宇
编辑 | Tina

世界正在发生变化,我们需要不断解决新的问题。

现在的一些企业应用,提供跨越全球的服务,并在云之间实时跳跃,使组织协同工作。应用程序必须能够全天候 7×24 运行实时响应,还必须具有超弹性、全球性和云原生能力。这种不断变化状态意味着遗留架构不足以或不适合满足现代组织的需求,无法应对大规模实时的挑战。

我们正在用云计算、微服务、物联网、事件中心等来满足这些新的、不断增长的需求。而数据是我们构建软件的命脉,因此涉及数据采集、存储、计算的操作占据了企业绝大多数开发人员的时间也就不足为奇了。作为一种实时数据的处理平台,消息系统的发展跟业务架构的变迁一直息息相关,那么我们可以透过业务架构的变化来看消息系统的发展历程和未来趋势。InfoQ 就此采访了阿里云中间件团队,以 RocketMQ 的发展来透视消息系统的演进过程。

采访嘉宾简介

林清山(花名:隆基),Apache RocketMQ 联合创始人,阿里云资深技术专家,阿里云消息产品线负责人。国际消息领域专家,致力于消息、实时计算、事件驱动等方向的研究与探索,推进 RocketMQ 云原生架构、超融合架构的演进。

周新宇(花名:尘央),Apache RocketMQ 联合创始人,阿里云高级技术专家,阿里云消息队列 RocketMQ 研发负责人。目前主要负责 Apache RocketMQ 5.0 面向消息和事件的架构升级,以及在阿里云的商业化落地。

1 消息系统是架构升级的关键
微服务和事件驱动

企业的业务架构一般都从“单体架构”开始,单体架构意味着开发、运维和迭代都非常简单,在这种架构下,消息传递主要采用同步方式。但是单体应用程序,是将许多功能紧密联系在一起,可扩展性是一个巨大的挑战。因此,企业的业务很快便向“分布式架构”演进,最终发展出了微服务架构,消息传递也变为了异步方式。

由于微服务是解耦的,它们可以更轻松地扩展,并且每当想要进行更改时,可以只更改一个组件。但是,仍然可能会遇到问题。所以为了克服这些问题,一些微服务应用程序采用了事件驱动的架构。经典微服务架构的主要缺点是同步服务调用之间的依赖关系,即使我们使用独立运营的服务,如果服务之间的耦合度很高,仍然可能存在部署依赖关系。

这时使用事件总线实现了服务的主要解耦。只要有一个动作,服务就会将一个事件发布到事件总线,并且一组特定的服务将订阅它。开发者可以使用许多技术将事件从一个组件流式传输到另一个组件,比如 RocketMQ、Kafka 这些消息系统都提供了流式服务,适合事件驱动的架构。

云原生架构

当业务上云逐渐成为一种共识,Docker 和 Kubernetes 逐渐成为主流,企业开始进行云原生改造,以提升用户体验并降低运维成本。

云原生架构基于微架构思想、以容器技术服务为载体,应用构成成分更加复杂。我们将构建一个分布式应用的复杂度分为“本质复杂度”和“次要复杂度”,在没有云原生之前,次要复杂度占了一个分布式应用的很大比例,开发者需要关心:应用本身需要多少 Server 进行部署,弹性和成本怎么取舍?各个组件运行时状态怎么收集和查询?可观测性指标如何搭建?依赖的软件,比如中间件和数据库,如何进行部署,稳定性如何保障?容量评估怎么做?存储的数据如何设计生命周期?如何进行归档?.......

云原生的应用,通过引入消息队列、函数计算、云原生数据库、对象存储等云原生的服务,可以很大程度上卸载这些次要复杂度,开发者真正有机会做到很纯粹地专注自身的业务逻辑。但云原生的应用因为依赖了大量云产品,不可避免构成的成分复杂了很多,所以消息队列在其中起到的“通道”和“粘合”的作用就至关重要了。

有人说,云原生体验的黄金标准是“无服务器”。函数计算(FaaS)或无服务器架构,应用的拆分粒度更小,通过函数构建的应用粒度更细,每个函数往往是单个操作,函数的编排和驱动面临着非常大的挑战。消息系统作为通道除了发挥“通信设施”作用,在函数计算场景,会进一步承担“集成与被集成”的角色,帮助函数计算编排函数,集成各类事件源,成为函数计算的驱动力。

2 跟随业务架构的迭代,消息队列做了哪些改变

最近一二十年里,随着业务架构的变化,出现了不少经典的消息中间件,比如 IBM MQ、ActiveMQ、RabbitMQ,扮演着“异步解耦”的角色,解决同步架构带来的耦合问题。互联网业务量爆发之后,由于传统的消息队列无法承受亿级用户的访问流量和海量数据传输,诞生了 Kafka、RocketMQ 这样的消息中间件。

Kafka、RocketMQ 诞生的背景和要针对性解决的问题又不完全一样。Kafka 诞生的背景是大数据,以批量,高吞吐等核心能力抢占了大数据管道的心智,随后非常自然地定位到 Streaming 领域。

而 RocketMQ 诞生背景跟阿里业务非常相关, 淘宝和天猫在 2008 年发起了一次最大规模的架构升级,启动了“五彩石”项目,把单体应用拆分成分布式应用,同时抽象淘宝、天猫的共同底座 - 业务中台,包括交易中心、商品中心、买家中心等。在业务中台之下,同时诞生了阿里中间件(初期三大件包括消息、RPC、分布式数据层),RocketMQ 是其中之一,除了异步与解耦,RocketMQ 需要更多地承担“堆积和削峰”的能力,以应对互联网业务的海量数据。

可以说,RocketMQ 诞生于“分布式架构”阶段,在这个阶段,业务对“分布式”并没有达成共识,各个公司对单体应用的拆分方式也是五花八门的,有垂直拆分,有水平分层,有按组件拆分,也有按服务拆分,但不管业务如何去落地分布式架构,消息系统在里面总是以“分布式通信”的原子能力去适配这些变化的,无论分布式应用是如何组织业务架构的,消息系统在这个阶段总是作为“分布式应用的通信基础设施”来助力业务架构的快速变迁,最终演进到较为理想的微服务架构。

在支撑阿里业务架构迭代的过程中,RocketMQ 发展为了 “全类型业务消息”,满足各种场景需求,这些消息可以说承担了相当于一部分的业务逻辑。另外,值得注意的是,微服务架构发展至今,特别是服务网格的思想兴起后,微服务形态呈现出多样化。在面临多样化的微服务生态时,消息系统需要通过强化自身被集成的能力,来更好的支持微服务技术架构的创新和演进。

但不管是 Dapr 还是 Knative,这些新兴的技术框架主要遵循两个关键思想:

  • 将分布式的基础能力进行下沉,比如植入到 Sidecar 当中,这些分布式的基础能力包括服务发现、负载均衡、远程调用、发布订阅(消息中间件)。

  • 对分布式能力进行抽象,新的微服务架构定义了抽象的 API,用于屏蔽分布式能力的具体实现,比如 Dapr 在其 DaprClient 中就对消息的 Pub/Sub 进行了全新的 API 定义;Knative 也基于 Kubernetes 的可扩展 API 定义了 Subscription 概念。

简而言之,新兴的微服务技术框架会将分布式应用需要的基础能力进行抽象和封装,并进一步植入到 Sidecar 或者自定义的 Runtime 当中。消息中间件作为分布式应用基础的通信能力,为了适配这些技术框架,需要加强自身的“被集成”能力。

所以 RocketMQ 也在不断新增功能,在 5.0 版本中有两个关键技术演进:

首先是轻量级 SDK,RocketMQ 在 5.0 版本中推出了基于 gRPC 全新的多语言 SDK,具备几个重要特点:

  • 采用全新极简的 API,拥有不可变 API 的设计,完善的错误处理,各语言 SDK API 在本地语言层面对齐,新的 API 化繁为简,更易被使用和集成。

  • 采用云原生的 RPC 标准框架 gRPC,标准的传输层框架,更易被拦截,特别适合被 Service Mesh 集成从而赋予其更多的传输层基础能力。

  • 客户端轻量化,以典型的“SimpleConsumer”为代表,采用全新的面向消息的无状态消费模型,整个 SDK 从代码到运行时都极为轻量。轻量化是一种非常重要能力,如果各个中间件都采取富客户端的形式,这些中间件当被一起植入到 Sidecar 中时,也会是一个非常庞大的 Sidecar,应用框架集成的复杂度非常高。

另一块就是无状态的消费模型,RocketMQ 5.0 引入了 Pop 机制,创新性地在队列模型之上支持了无状态的消息模型,在一个主体上同时支持两种消费模型,体现了消息和流的“二象性”,面向流场景采用高性能的队列模型进行消费,面向消息的场景,采用无状态的消息模型进行消费,业务可以只关心消息本身,通过“SimpleConsumer”提供单条消息级别的消费、重试、修改不可见时间、以及删除等 API 能力。

适配云原生

近两年,包括中间件、数据库等各类云产品都宣称完成了云原生升级,RocketMQ 也开始全面走向多样化、标准化一级云原生化,同时在 IoT、边缘计算、事件驱动等新趋势进行相应的布局和落地实现。

在适应云原生改造时,RocketMQ 在计算、存储、和网络三个方面都有重大升级,让 RocketMQ 能充分利用云的弹性能力,撬动云的计算、存储和网络的池化资源,满足用户的各类弹性需求:

  • 在计算层面,RocketMQ 5.0 通过 ACK 充分利用 ECS 弹性能力,采取弹性资源池 + HPA 相关技术支持计算能力快速弹性,同时 ACK 自带的跨可用区部署能力为云产品提供了充足的高可用保障。

  • 在网络层面,RocketMQ 接入了阿里云的多种网络能力,满足用户对多样性网络的需求,公网随开随用,支持多种私网网络形态,基于 CEN 构建了全球互通的消息网络。

  • 在存储方面,通过推出多级存储产品化的能力,充分利用 OSS 存储的弹性能力,存储计费走向按量付费,同时支持冷热数据分离,为用户提供一致的冷读 SLA。

完成云原生升级的应用构成成分更加复杂,以前多个微服务 + 数据库可能就组合成了一个应用,计算在微服务,存储在数据库。但云原生化后,计算的形态有很多种,比如可能隐藏在一个 API 网关后面,或者是一个函数计算的形态,又或者是一个容器服务的 Job。数据也散落存储在各个地方,中间件、数据库、大数据、对象存储等各个领域都提供了数据的存储与访问能力。

显而易见的是,云原生化的应用虽然能够充分撬动云的能力,但对研发团队来讲,整个应用生命周期的各个环节的都需要有新的工具和流程来进行规范化生产。

在云原生、微服务、事件驱动架构的发展形式下,我们需要 RocketMQ 这样的消息队列起到“集成”和“粘合”众多不同场景、不同形式的各种业务。

另外,RocketMQ 提供了大量的消息治理能力,包括消息回放、消息重试、死信消息等。大家都知道互联网业务对可用性有着极高的追求,阿里内部的数据库和中间件在各个商业化版本里面都提供了容灾能力,来满足互联网用户对于容灾高可用需求。RocketMQ 创新性地通过组合流量管控和数据复制“全球消息路由”方面的技术沉淀提供了多活和灾备的解决方案。

总结下来,消息队列在发展的过程当中,从最初的帮助业务进行“异步解耦”,到互联网时代的堆积和削峰,再到后来从架构层面深入到业务层面,通过不同的业务消息来沉淀通用的开发范式,到最后通过领先的消息治理和服务能力,来满足互联网业务对业务管控和多活容灾等方面的需求。可以说 RocketMQ 发展至今已经深入到了业务的架构、开发范式、运维管控、可观测性、容灾架构等方方面面。

从行业对比来看 RocketMQ 的性能

经过十多年的发展,RocketMQ 逐渐成为了一个消息、事件、和流一体的超融合处理平台。

消息领域,全面拥抱云原生技术,弹性伸缩,开箱即用。在事件领域,产品形态全面升级,拥抱行业标准,让事件驱动架构无处不在,从单一业务的数字化系统,扩展到跨业务、跨组织的数字化商业生态。事件驱动架构同时也让云计算、云原生的技术能够更大规模的落地,提高云产品和用户业务的集成度,让 Serverless 技术被更大范围的采纳,为客户降本增效。在领域,流存储增强批量特性,大幅度提高数据吞吐量;新增逻辑队列能力,解耦逻辑资源和物理资源,在流场景也具备无缝伸缩能力;新增轻量流处理引擎,提供实时事件流处理、流分析能力。

目前,行业中,Kafka 作为主流消息系统之一,为大家广为熟悉。从可用性和可靠性方面看,Kafka 有多副本机制,首领副本挂掉的话可以选举出新首领,继续提供服务。从功能方面看,较新版 kakfa 还支持精确性一次语义和事务。

跟行业对比,从可用性和可靠性上来看,RocketMQ 也有多副本机制,并经历了多个版本的演进,随着 RocketMQ 面向的场景的变化而变化,也即是说 RocketMQ 的多副本技术是服务于业务的变化的,并不是一成不变的,这其实也体现了 RocketMQ 架构上的灵活性。这也是跟行业相比最大的不同,行业的大部分多副本解决方案跟架构耦合比较深,基本上是一成不变的。

  • RocketMQ 最开始采取的 Master-Slave 架构,该架构服务于阿里内部淘系业务多年,当时业务上架构的诉求其实就是数据冷备,那个阶段包括数据库都是 Master-Slave 的架构。

  • 到上云的阶段,云的时代单点故障频发,云产品需要完全面向失败而设计,故 RocketMQ 开发了基于 ZK 的 HA 架构,该架构从未开源,属于商业上的版本,依托于 Zookeeper 的分布式锁和通知机制,引入 Controller 组件负责 Broker 状态的监控以及主备状态机转换,在主不可用时,备自动切换为主。

  • 再到后来,业务除了关注可用性,也越来越多地关注“故障恢复时间”,也就是 RTO 指标,基于 ZK 或者 开源基于 Raft 的多副本版本 RTO 时间都较长,为了解决这个问题,商业上针对业务消息,设计了“秒级 RTO”多副本架构,包含无切换设计、节点对等、灵活 ACK、特殊消息故障转移等设计能够将集群故障恢复时间降低到秒级。

  • 到 RocketMQ 5.0,需要同时面向消息和流的场景,对多副本技术有了非常高的要求,一方面在业务消息期望集群有超短的故障转移时间,另一方面流要求分区永不下线,基于这个背景,在 5.0 这个大版本当中,将商业上的秒级 RTO 架构与开源的 Dledger Controller 进行了融合,统一了消息和流的多副本方案。

从功能上看,在精确性一次语义和事务上,RocketMQ 的事务能力,匹配的产品是 IBM MQ,其事务消息是面向金融级业务的,其采取的是分布式事务的 XA 模式,实现的方式还是非常重的,性能也不够高。另外,Kafka 事务面向的场景主要是流计算,解决的问题是数据通过框架经过 Kafka 时做到不重复不丢失,这确实是对流计算框架非常有用的一个设计,但 Kafka 的事务并不会考虑业务逻辑的事务性,从阿里云商业化的角度看,鲜有用户将 Kafka 用于核心交易链路。

相比之下,RocketMQ 最终一致的事务消息机制,性能更高,也更适合微服务分布式架构,RocketMQ 的事务消息也是脱胎于淘宝交易链路的真实需求,目前在交易链路也是被广泛使用的。另外,RocketMQ 在金融场景里多有应用,金融级的业务,除了事务性,对消息的服务和治理能力要求更高的,比如消息的重试、死信、回溯、轨迹、重投等,也包括可用性和可靠性等。

从性能上来讲,对于吞吐量,RocketMQ 在 2017 年就能优化到单机 50W 的 TPS,后续在阿里内部甚至优化到了单机 100W TPS,这还是单条消息的性能(非批量),但实际上从生产环境的稳定性,以及业务消息的重要性来讲,阿里从来没有在生产环境部署过这么高 TPS 的负载。如果是在批量的场景,行业各个消息队列我相信都能轻易地打满网络带宽或者磁盘资源。换句话说,性能是很难作为一个产品的核心竞争力的,除非是架构层面有限制,一般情况下差异都不大。RocketMQ 当前的性能是足够用的,即使是以高性能著称的 Kafka,在阿里云上 RocketMQ 都能作为其内核支撑阿里云 Kafka 的业务场景。

延迟是一个非常重要的指标,在延迟这个指标后面长尾延迟,也就是常说的毛刺更是重中之重,在线业务对于是 2ms 延时和 5ms 延时基本上都能接受,但非常难以接受的是经常性有秒级的毛刺。RocketMQ 曾经在内部双十一场景被诟病最多的就是毛刺,在 2016 年 RocketMQ 团队耗费了很大的精力打造了低延迟的存储引擎,非常顺滑地支持了这么多年的双十一,这也是 RocketMQ 能非常好地支持在线业务的一个主要原因。

除了这两点,弹性和可扩展能力也是非常重要的,单机性能再高,不能充分利用云上的弹性资源就不能算是云原生时代的解决方案。甚至从稳定性的角度来讲,控制单机的规格和性能上限,以横向扩展的方式支撑业务的弹性需求是更稳定更健康的一种方式。

3 消息系统的未来

对于 RocketMQ 来讲,核心架构大约经历了五次重要的演进阶段,但一开始的架构设计得非常简洁,比如元数据采用最终一致性的设计,只引入了核心代码仅几百行的 NameSrv 组件,且是无状态的,相比其他产品依赖 ZK 进行元数据的管理维护,RocketMQ 的优势是显而易见的。除此之外,RocketMQ 相比于其他消息产品采用了 Shared Nothing 架构,因此整体更加的稳定,有着更小的爆炸半径,独特的读写权限设计,提升了 RocketMQ 可运维性的同时,为弹性扩缩也打下了坚实基础。

在前四次迭代中,头两次初步打磨了自研的存储引擎, 第三次迭代前瞻性地去除了 ZooKeeper 等组件的外部依赖,并支持了单机海量 Topic。第四次迭代重点优化了高可靠低延迟方面的性能。

为了适应业务架构变化,2018 年之后,RocketMQ 开始策划第五个大版本,新增或者修改了超过 60% 的代码,主要包括几个方面:

  • 流计算相关:开源至 Apache 的 rocketmq-streams 以及开源至 Alibaba 的 rsqldb。

  • 事件驱动相关:rocketmq-eventbridge

  • 架构升级相关:这块主要在 RocketMQ 主仓库,包括 HA 架构的统一、流存储相关的 Compact Topic、逻辑队列、Batch、无状态消息模型相关的 Proxy、Pop 机制、基于 gRPC 的全新多语言轻量级 SDK 等。

5.0 包含了非常多的新功能,为提高稳定性,RocketMQ 布局了完善的 Committer 代码 Review 机制、CI/CD 等基础设施。同时,在版本发布前会进行稳定性相关测试,RocketMQ 5.0 新版本也经过了非常严苛的故障注入测试,并利用 OpenChaos 针对多种极端的故障场景。另外,新增的能力基本上在阿里内部都有比较大的规模落地,比如 rocketmq-streams 在内部安全相关的业务,在专有云都有输出,流存储相关的设计在阿里云 Kafka 产品上也有非常大规模的落地......

在未来的趋势上,RocketMQ 团队认为消息队列会往以下三个方向进一步的演进:

  • 第一个趋势是全面拥抱云原生,向上消息产品形态演进,支撑云原生应用架构(微服务、EDA)。比如微服务、事件驱动、Serverless 等现代化架构,向下消息系统自身进行云原生架构演进,要通过一系列的技术改造,充分释放云基础设施的弹性计算、弹性存储、弹性网络等能力,全方位提高消息的技术指标,降低成本,提高弹性能力。

  • 第二个趋势是拥抱物联网。物联网技术将更广泛的落地到各行各业,万物互联、边缘计算进一步拓展消息的边界。面向物联网的消息队列要海量异构设备接入,海量消息队列存储,能够随处运行,具备云边端一体的无边界部署能力。

  • 第三个趋势是拥抱实时数据。现在企业的数字化转型又往前迈进了一步。从原来的业务数字化迈进到了数字业务化,数字化企业持续产生业务数据,对业务数据的实时洞察、实时决策,能快速把握商机,指导业务获得更大的成功。消息队列也将从在线业务架构基础设施,延伸到实时数据架构基础设施,事务分析一体化。

而从更远的未来看,消息系统的架构会有几个方向:

  • 流存储或者流数据库方向:消息作为管道,天然就是流的形态,其存储的数据也是流式的数据,所以消息系统往流数据库方向发展也是非常自然的一件事情。

  • 云原生通信标准:在云原生时代,消息的一个重要定位是应用之间通信基础设施,它在应用层的定位,是类似 TCP 在网络层的定位。但目前消息系统还比较碎片化,离这一步还有非常远的距离。

  • 软硬件深度结合:目前并没有针对消息的新型硬件的创新,但在未来不管是流存储,或者是作为应用层开箱即用的通信设施,消息系统都需要有适配的硬件来达到一个性能、成本和规模相平衡的状态。比如业界针对 Append-Only 类型的业务在研究 Zone Storage 技术,包括相应的 ZNS 技术规范、文件系统以及存储实现。

最后,基于社区 Apache RocketMQ 5.0 的阿里云商业版即将在 8 月初正式发布,欢迎大家关注。

关注公众号:拾黑(shiheibook)了解更多

[广告]赞助链接:

四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

公众号 关注网络尖刀微信公众号
随时掌握互联网精彩
赞助链接