2022年3月23日

消息驱动、事件驱动、流”基础概念解析
阿里云消息队列 RocketMQ 5.0 实现了全新升级,实现了从“消息”到“消息、事件、流”的大融合,基于此,MessageDriven、EventDriven、Streaming 这三个词是近期消息领域高频词,但由于概念过于新,很多同学其实是不太理解这里的异同。本文把三个概念重新整理下,梳理出比较明确的概念讲给大家。 背景 首先这三个概念具体翻译如下: MessageDriven:消息驱动的通信; Event Driven:事件驱动的通信; Streaming:流模式。 这三个模式都是类似异步通信的模式,发送消息的服务不会等待消费消息服务响应任何数据,做服务解耦是三个模式共同的特性; 只要是在服务通讯领域内,在选型时还要考虑如下特性: 排序:是否可以保证特定的顺序交付; 事务:生产者或消费者是否可以参与分布式事务; 持久化:数据如何被持久化,以及是否可以重放数据; 订阅过滤:是否拥有根据Tag或其他字段做订阅过滤的能力; At – least once(最少交付一次),Atmostonce(最多交付一次),Exactlyonce (精确交付)。 通用背景介绍完,依次来看看各个模型代表的是什么意思。 消息驱动 MessageDriven 在消息驱动通信中,一般链路就是消息生产者(Producer)向消息消费者(Consumer)发送消息。模型如下: 消息驱动模式下通常会用到中间件,比较常见的中间组件有 RocketMQ,Kafka,RabbitMQ 等。这些中间件的目的是缓存生产者投递的消息直到消费者准备接收这些消息,以此将两端系统解耦。 在消息驱动架构中,消息的格式是基于消费者的需求制定的;消息传递可以是一对一,多对多,一对多或多对一。 消息驱动通讯比较常见的一个例子是商品订单推送,上游组件负责生成订单,下游组件负责接收订单并处理。通过这样的通讯方式上游生成组件其实无需关心整个订单的生命周期,更专注于如何快速生成订单,使单个组件的性能得以提升。 消息驱动模式在服务之间提供了轻的耦合(这部分耦合指代 Producer/Consumer SDK),并可以对生产和消费服务根据诉求进行扩展。 事件驱动 EventDriven 首先要申明一个观点:事件驱动其实是对消息驱动方法的改进,它对消息体大小,消息格式做了较为严格的限制,这层基于消息的限制封装其实就称为事件(Event)。 在事件驱动模式中,生产者发布事件来表示系统变更,任何感兴趣且有权限接入的服务都可以订阅这些事件,并将这些事件作为触发器来启动某些逻辑/存储/任务。 事件驱动的模式可以是一对一,多对一,一对多或多对多。通常情况下一般是多个目标根据过滤条件执行不同的事件。 在事件驱动架构中,事件的格式是由生产者根据事件标准协议制定的;由于更规范限制和封装,事件的生产者完全不需要关心有哪些系统正在消费它生成的事件。 事件不是命令,事件不会告诉消费者如何处理信息,他们的作用只是告诉消费者此时此刻有个事件发生了;事件是一份不可变的数据,重要的数据,它与消息的数据价值相同;通常情况下当某个事件发生并执行时,往往伴随着另一个事件的产生。 事件驱动提供了服务间的最小耦合,并允许生产服务和消费服务根据需求进行扩展;事件驱动可以在不影响现有服务的情况下添加各类新增组件。 事件驱动也可以举一个非常贴切的例子,我们以“客户购买完一款商品”为一个事件,举证在事件场景的应用: CRM(客户关系系统)系统接收到客户购买信息,可自行更新客户的购买记录; EMR(库存管理系统) 系统接收到客户购买信息,动态调整库存并及时补货; 快递服务接收到客户购买信息,自行打单并通知快递公司派送。 这么看,事件驱动模式是不是可以应用并出现在任何地方! 在 EventBridge 产品化方向,也正是由于针对消息做了一些标准化封装,才有可能实现譬如针对事件本身的 filter(过滤) ,transform(转换),schema(事件结构),search(查询) 等能力。这些能力也拓展出更多针对事件驱动特有的场景功能及相关特性。 流 Streaming 流是一组有序的无界事件或数据,执行操作通常是固定的某个事件段(e.g. 00:00 – 12:00)或一个相对事件(E.g. 过去 12 小时)。 通常情况下单个事件往往就是使用事件本身,但是对于流可能的操作大概率是过滤,组合,拆分,映射等等。 流的操作可以是无状态也可以是有状态的: 对于单个事件操作是无状态的,包括过滤和映射; 依赖消息在流的时间或位置(e.g. offset,time)是有状态的。有状态操作中,流处理逻辑必须保留一些已被消费消息的内存。有状态包括对数据做 Batch Size,Batch Window 等。 流这里也可以举一个比较简单的例子,比如我们的物流系统在物品通过一个物流节点时会生成一个事件,但是要查到这个物品完整的流转状态事件,则必须是各个物流节点单个事件的聚合,那这个聚合事件就是流事件。 Kafka 是最典型的流式中间件,在流式场景中,事件的位置信息至关重要。通常情况下位置信息(E.g. offset)是由消费者托管的。 事件规范标准 聊完 Event 和 Streaming 是什么,再来补充一点有关于它们的规范。 事件规范存在的目的是为了清晰事件生产者和消费者的关系,目前主要有两部分:AsyncAPI 和 CloudEvents; AsyncAPI:基于事件 API 提供了与之对应的 Open API 和 Swagger 等;CloudEvents:侧重于处理事件的元数据。 下面也重点介绍一些关于 CloudEvents 的相关概念参考:CloudEvents 的核心其实是定义了一组关于不同组件间传输事件的元数据,以及这些元数据应该如何出现在消息体中。 其主旨大抵如下: 事件规范化; 降低平台集成难度; 提高 FaaS 的可移植性; 源事件可追踪; 提升事件关联性 准确的事件体,事件信息才可以做出更稳定的系统架构,永远保持对事件的敬畏。 附 一些术语及定义: Occurrence:发生,指事件逻辑上的发生,基于某种情况,事件出现了; Event:事件,表示事件以及上下文的数据记录。可以根据事件中的信息决定路由,但事件本身并不包含路由信息; Producer:生产者,真正创造事件的实例或组件; Source:源,事件发生的上下文,可以由多个 producer 组成; Consumer:消费者,接收事件并对事件进行消费; Intermediary:中介,接收包含事件的消息(message),并转发给下一个接收方,类似路由器; Context:上下文,上下文元数据被封装到 context attributes 中,用来判断事件与其它系统的关系; Data:数据,也可以叫做 payload; EventFormat:事件格式,例如 json; Message:消息,封装事件并将其从 source 传递到 destination; Protocol:协议,可以是行业标准如 http,开源协议如 Kafka 或者供应商协议如 AWS Kinesis; Protocol Binding:协议绑定,描述如何通过给定的协议收发事件,如何将事件放到消息里。 活动推荐 阿里云基于 Apache RocketMQ 构建的企业级产品消息队列RocketMQ 5.0版现开启活动: 1、新用户首次购买包年包月,即可享受全系列 85折优惠! 了解活动详情:
作者:肯梦
#技术探索 #事件驱动架构

2022年3月18日

EventBridge 事件总线及 EDA 架构解析
作为 Gartner 定义的 10 大战略技术趋势之一,事件驱动架构(EDA)逐渐成为主流技术架构。根据 Gartner 的预估,在新型数字化商业的解决方案中,将有 60%使用 EDA,在商业组织参与的技术栈中,EDA 有一半的占比。 当下比较成功的企业已然认识到,要想最大限度提升运营效率和客户体验,务必要将业务和技术两方面的举措紧密结合起来。运营事件或业务形势的变化是时下众多企业关注的焦点,这些变化能够为企业领导者带来切实有用的信息,而架构设计的主旨恰恰是从客户联系人、交易、运营等方面的信息中获取洞见,两者相辅相成。传统技术历来对企业从事件中获取洞见的速度有着诸多限制,比如用于记录、收集和处理此类事件的批处理 ETL(提取、转换、加载)等。基于以上背景,阿里云 EventBridge 应运而生。 EventBridge 是事件驱动的具体落地产品,也是 EDA 的最佳实践方式。 事件驱动(EDA)是什么 早在 2018 年,Gartner 评估报告将 EventDriven Model 列为 10 大战略技术趋势之一,事件驱动架构(EDA)将成为未来微服务的主流。该报告同时做出了以下断言: 到 2022 年,事件通知的软件模型将成为超过 60% 的新型数字化商业的解决方案; 到 2022 年,超过 50% 的商业组织将参与到事件驱动的数字化商业服务的生态系统当中。 很喜欢 George Santayana 在《 The Life of Reason》说的一句话 Those who fail to learn History are doomed to repeat it.(不懂历史的人注定会重蹈覆辙)。我们以史为鉴,来看看为什么会架构会演进到事件驱动。 上图是关于架构演进时间轴线。架构本身没有优劣之分,它本身就是一组技术决策,决定后续项目的所有功能开发(框架,编码规范,文档,流程….),所以这里不谈选型好坏,只谈为什么会引入某些框架,这个框架解决了软件开发中的什么问题。 单体架构:在单节点服务中,单体应用的所有模块都封装在单个进程运行,通信通过相同堆栈调用完成。这种模式下非常容易导致结构和关系不明确,难以对系统进行更改和重构。就像一个不透明的,粘稠的,脆弱的,僵硬的 Big Ball of Mud! 分层架构:在经典的分层架构中,层以相当谨慎的方式使用。即一个层只能知道它下方层的数据。在随后的实际应用中,更多的方式是一个层可以访问它下面的任何层。分层架构解决了单体架构的的逻辑分离问题,每一层都可以被等效替换,是用层区分也更加标准化,同时一个层可以被几个不同/更高级别的层使用。当然,层也有比较明显的缺点,层不能封装掉一切,比如添加到 UI 的某个字段,可能也需要添加到 DB,而且额外多余的层会严重损害系统性能。 MVC 架构:MVC 架构产生的原因其实很简单,随着业务系统的复杂性增加,之前所谓“全栈工程师”已经不适用大部分场景。为了降低前端和后台的集成复杂性,故而开始推广 MVC 架构。其中,Model 代表业务逻辑;View 代表视图层,比如前端 UI 的某个小组件;Controller 提供 View 和 Model 的协调,比如将用户某项操作转为业务逻辑等。此外还有很多扩展架构,譬如 ModelViewPresenter,ModelViewPresenterViewModel,ResourceMethodRepresentation,ActionDomainResponder 就不在细说了,感兴趣的同学可以 wiki 搜索下。 EBI 架构:即 Entity,Boundary(接口),Interactor (控制)。EBI 架构将系统边界视为完整连接,而不仅仅是视图,控制器或接口。EBI 的实体代表持有数据并结束相关行为的实际实体,很类似阿里云的 POP API。EBI 主要还是后端概念,它是与 MVC 相辅相成的。 洋葱架构:洋葱架构是一种低耦合,高内聚的架构模型。所有的应用程序围绕独立的对象模型构建,内层定义接口,外层实现接口,耦合方向向中心内聚,所有代码都可以独立与基础设施进行编译和运行。 SOA 架构:SOA 是 Service Orientated Architure 的缩写,即面向服务架构。表示每一个功能都是通过一个独立的服务来提供,服务定义了明确的可调用接口,服务之间的编排调用可完成一个完整的业务。其实这个架构也是目前架构中最成熟的,日常使用最多的架构模式。 在介绍完之前全部的架构趋势后,在回过头看看什么是 EDA 架构。 EDA 事件驱动架构( EventDriven Architecture ) 是一种系统架构模型,它的核心能力在于能够发现系统“事件”或重要的业务时刻(例如交易节点、站点访问等)并实时或接近实时地对相应的事件采取必要行动。这种模式取代了传统的“ request/response ”模型,在这种传统架构中,服务必须等待回复才能进入下一个任务。事件驱动架构的流程是由事件提供运行的。 上图其实很好的解释了 EDA 架构的模型,但是其实还不够明确,所以这里我们和单体架构一起对比看看他们之间差异。 在如上对比图中,我们其实可以较为清楚看到它与传统架构的区别。在一般传统架构中,创建订单操作发生后,一系列的操作其实都是通过一个系统完成的。而事件驱动的概念则是将全部操作都转换为 “事件” 概念,下游通过捕获某个 “事件” 来决定调用什么系统完成什么样的操作。 我们回过头来看“事件”,刚刚介绍中比较的重要部分其实是将操作转换为某类事件进行分发。那这的事件我们怎么定义呢? 简单来看,其实事件就是状态的显著变化,当用户采取特定行动时触发。以 4S 店售卖汽车为例: 当客户购买汽车并且其状态从 For Sale 变为 Sold 是一个事件; 成功交易后,从帐户中扣除金额是一个事件; 单击预订试驾后,从将预约信息添加到指定用户就是一个事件; 每个事件都可能触发一个或多个选项作为响应。 事件其实云原生 CNCF 基金会在 2018 年托管了开源 CloudEvents 项目,该项目旨在用统一和规范的格式来描述事件,来加强不同的服务、平台以及系统之间的互操作性。在该项目定义下,通用的事件规范是这样的: 事件主要由 Json 体构成,通过不同字段描述发生的事件。 总结来看,事件驱动其实是将比较重要的业务时刻封装成“事件”,并通过某个 EventBus 将事件路由给下游系统。 了解了 EDA 架构的整个处理过程,但是还没解决这个所谓的“EventBus”到底是什么? 如上图就是 EventBus 的核心逻辑架构,它由 Event Producer 和 Event Consumer 两端组成,通过 Bus 解耦中间环节,是不是非常像某个传统的 MQ 架构?别着急,在接下来的落地实践部分会讲解这个架构的复杂部分。 EDA 架构的落地实践思考 在开始介绍落地实践时,我们先来看一个经典的 EDA 架构模型: 这是一个非常经典 EDA 订单架构,该架构主要使用了 EventBridge 和 FC 函数计算(如果不太熟悉 FaaS 的同学可以把 FC 节点当作 ECS 或 Kubernetes 的某个 POD 节点),通过事件驱动各个业务进行协作。 所以这块的中心节点(EventBridge)其实有三个比较重要的能力: 1. For Event Capturing(事件收集):具备采集事件的能力; 2. For Routing(事件路由):通过事件内容将事件路由分发至于下游的能力; 3. For Event Processing(事件过滤/替换):对事件进行脱敏或初步过滤&筛选的能力。 通常情况下,要实现这三个能力是比较困难的,比如:Event Capturing 可能需要熟悉 Dell Boomi, Snaplogic, MuleSoft, Dataflow, Apache Apex 等,Routing 部分可能通过 RocketMQ、RabbitMQ、ActiveMQ、Apache Kafka,Event Processing 需要了解 Apache Storm, Apache Flink 。所以之前讲的逻辑架构其实非常理想,要想实现完成的 EDA 事件驱动还需要包括这些核心能力。 其实,从刚刚的架构中我们也能窥探到一些信息,EDA 架构其实看起来没有那么简单,那它有何优劣呢? 下面简单罗列下 EDA 架构在实践中的优势: 松耦合:事件驱动架构是高度松耦合且高度分布式的架构模型,事件的创建者(来源)只知道发生的事件,并不知道事件的处理方式,也关心有多少相关方订阅该事件; 异步执行:EDA 架构是异步场景下最适合的执行工具,我们可以将需要事件保留在队列中,直到状态正常后执行; 可扩展性:事件驱动架构可以通过路由&过滤能力快速划分服务,提供更便捷的扩展与路由分发; 敏捷性:事件驱动架构可以通过将事件分发至任何地方,提供更敏捷高效的部署方案。 当然,劣势也很明显: 架构复杂:事件驱动架构复杂,路由节点多,系统结成复杂,功能要求多; 路由分发难:事件路由分发难,灵活的事件路由需要依赖强大的实时计算能力,对整体分发系统要求较高; 无法追踪:事件追踪是整个 EDA 架构的保证,EDA 架构中往往很难追踪到事件处理状态,需要大量的定制化开发; 可靠性差:事件驱动由于需要多系统集成,可靠性通常较差,且交付无法保障。 _ 针对 EDA 场景面临的这些问题,阿里云推出了 EventBridge,一款无服务器事件总线服务,其使命是作为云事件的枢纽,以标准化的 CloudEvents 1.0 协议连接云产品和应用、应用和应用,提供中心化的事件治理和驱动能力,帮助用户轻松构建松耦合、分布式的事件驱动架构;另外,在阿里云之外的云市场上有海量垂直领域的 SaaS 服务,EventBridge 将以出色的跨产品、跨组织以及跨云的集成与被集成能力,助力客户打造一个完整的、事件驱动的、高效可控的上云体验。 阿里云对 EventBridge 做了定义,核心价值包括: 统一事件枢纽:统一事件界面,定义事件标准,打破云产品事件孤岛; 事件驱动引擎:海量事件源,毫秒级触发能力,加速 EDA/Serverless 架构升级; 开放与集成:提供丰富的跨产品、跨平台连接能力,促进云产品、应用程序、SaaS 服务相互集成。 下面从架构层面和功能层面对 EventBridge 进行介绍: 架构层面 针对架构复杂问题,EventBridge 提供业内通用的 Source ,Buses,Rules,Targets 模块管理能力,同时支持 EventBus 和 EventStream 两种模式,大幅度降低事件驱动架构难度。 1)事件总线模型经典 EDA( 事件驱动)场景的 N:N 模型,提供多事件路由,事件匹配,事件转换等核心能力,帮助开发者快速搭建事件驱动架构。 2)事件流模型标准 Streaming(1:1) 流式处理场景,无总线概念,用于端到端的数据转储,数据同步及数据处理等,帮助轻松构建云上端到端的数据管道服务。 功能层面 在功能层面,EventBridge 的核心亮点应用包括: 1)事件规则驱动 针对基于事件的路由分发,EventBridge 通过事件规则驱动,支持 8 大事件模式,4 重转换器,满足路由分发的全部诉求。 2)事件追踪 针对事件无法追踪,独家提供事件追踪能力,事件分析/查询能力。为用户完善的全链路事件查询分析能力。 3)DLQ/重试机制、事件全流程触发 针对可靠性差,支持 DLQ/重试机制,与事件全流程触发,大幅度保证由于用户下游系统导致的事件故障与延迟。 4)Schema 注册中心 针对事件管理复杂,支持 Schema 注册中心,支持事件信息的解释、预览和上下游代码生成能力,帮助用户低代码完成事件的收发处理。解决跨部门信息沟通困难,业务代码冗余等一系列事件管理问题。 5)同时,基于以上功能 EventBridge 支持对接 85 种以上的阿里云产品,847 种事件类型。 更多产品功能介绍,可访问 EventBridge 官网 阿里云 EventBridge 更多场景介绍 经典 EDA 事件驱动 事件总线(EventBridge)最重要的能力是通过连接应用程序、云服务和 Serverless 服务来构建 EDA(Eventdriven Architectures) 事件驱动架构,驱动应用与应用,应用与云的连接。 流式 ETL 场景 EventBridge 另一个核心能力是为流式的数据管道的责任,提供基础的过滤和转换的能力,在不同的数据仓库之间、数据处理程序之间、数据分析和处理系统之间进行数据同步/跨地域备份等场景,连接不同的系统与不同服务。 统一事件通知服务 EventBridge 提供丰富的云产品事件源与事件的全生命周期管理工具,您可以通过总线直接监听云产品产生的数据,并上报至监控,通知等下游服务。 活动推荐 阿里云基于 Apache RocketMQ 构建的企业级产品消息队列RocketMQ 5.0版现开启活动: 1、新用户首次购买包年包月,即可享受全系列 85折优惠! 了解活动详情:
作者:肯梦
#技术探索 #事件驱动架构

2022年2月22日

EventBridge消息路由|高效构建消息路由能力
企业数字化转型过程中,天然会遇到消息路由,异地多活,协议适配,消息备份等场景。本篇主要通过 EventBridge 消息路由的应用场景和应用实验介绍,帮助大家了解如何通过 EventBridge 的消息路由高效构建消息路由能力。 背景知识 EventBridge 消息路由主要涉及以下云产品和服务: 事件总线 EventBridge 事件总线 EventBridge 是阿里云提供的一款无服务器事件总线服务,支持阿里云服务、自定义应用、SaaS 应用以标准化、中心化的方式接入,并能够以标准化的 CloudEvents 1.0 协议在这些应用之间路由事件,帮助您轻松构建松耦合、分布式的事件驱动架构。 消息队列 RabbitMQ 版 阿里云消息队列 RabbitMQ 版支持 AMQP 协议,完全兼容 RabbitMQ 开源生态以及多语言客户端,打造分布式、高吞吐、低延迟、高可扩展的云消息服务。开箱即用,用户无需部署免运维,轻松实现快速上云,阿里云提供全托管服务,更专业、更可靠、更安全。 消息队列 MNS 版 阿里云消息服务 MNS 版是一款高效、可靠、安全、便捷、可弹性扩展的分布式消息通知服务。MNS 能够帮助应用开发者在他们应用的分布式组件上自由的传递数据、通知消息,构建松耦合系统。 场景应用 EventBridge 消息路由功能在构建在构建消息系统过程中主要应用于下面三个场景,一是消息路由场景,二是消息多活场景,三是多协议适配场景,下面对这三个场景进行简要介绍。 消息路由场景 该场景是指希望对消息进行二次分发,通过简单过滤或者筛选将消息分发到其他 Topic 或跨地域 Topic,实现消息共享 & 消息脱敏的场景。 通过一层转发将消息分发给不同的 Topic 消费,是消息路由的核心能力。随着企业转型遇到消息拆分且做业务脱敏的场景会越来越多。如下图是一个较为典型的路由分流场景。 消息多活场景 消息多活场景指每个数据中心均部署了完整、独立的 MQ 集群。数据中心内的应用服务只连接本地的 MQ 集群,不连接其他单元的 MQ 集群。MQ 集群中包含的消息路由模块,负责在不同单元 MQ 集群之间同步指定主题的消息。 根据应用服务是否具有单元化能力,可分为中心服务和单元服务两类。中心服务只在一个数据中心提供服务;单元服务在各个数据中心都提供服务,但只负责符合规则的部分用户,而非全量用户。 所有部署了单元服务的数据中心都是一个单元,所有单元的单元服务同时对外提供服务,从而形成一个异地多活架构或者叫单元化架构。通过多活管控平台可动态调整各个单元服务负责的流量。 多协议适配场景 随着业务团队的逐渐庞大,对消息的建设诉求与日俱增,由于部门技术栈的不同会导致部门间的消息协议也不尽相同。多协议适配是指用一种消息协议平滑迁移到多种消息协议的能力。 架构描述 使用 EventBridge 的事件流能力做消息路由,事件流模型是 EventBridge 在消息领域主打的处理模型,适用标准 Streaming(1:1)流式处理场景,无总线概念。用于端到端的消息路由,消息转储,消息同步及处理等,帮助开发者轻松构建云上数据管道服务。 下面的架构展示了如何通过桥接 EventBridge 实现 MNS 消息路由至 RabbitMQ Queues,MNS Queues。(A/B 链路任选其一进行试验) 应用实验 目标 通过本实验教程的操作,您可以通过阿里云控制台,在事件总线控制台中创建消息路由服务,在 EventBridge 控制台实现消息路由与简单的消息脱敏。 体验此实验后,可以掌握的知识有: 创建消息路由任务; 创建 RabbitMQ 实例、MNS 实例与简单的消息发送。 资源 使用到的资源如下:(本次实验资源遵循最小原则,使用满足场景需求的最小化资源) 资源一:EventBridge 事件总线 资源二:阿里云消息队列 RabbitMQ 版 资源三:阿里云消息队列 MNS 版 步骤 1)创建 MNS 资源 本实验分 A /B 两个可选场景: A 、场景通过 MNS Queues1 投递至 MNS Queues2 B 、场景通过 MNS Queues1 投递至 RabbitMQ Queues 可根据兴趣选择不同场景。 本步骤将指导您如何通过控制台创建消息队列 MNS 版。 使用您自己的阿里云账号登录阿里云控制台,然后访问消息队列MNS版控制台。[1] 在控制台左边导航栏中,单击队列列表。(资源地域为同地域即可,本次引导默认选杭州) 在列表页面,单击创建队列并填写名称信息“testmnsq” 创建完成后点击“详情” 找到 MNS 公网接入点信息,并记住该信息,后续实验会用到。 E.g. 注意:重复如上步骤即可创建 A 实验链路的 “testmnsq2” 2)创建 RabbitMQ 资源(B 实验可选) 本步骤将指导您如何通过控制台创建消息队列 RabbitMQ 版。 使用您自己的阿里云账号登录阿里云控制台,然后访问消息队列RabbitMQ版控制台。[2] 在控制台左边导航栏中,单击实例列表。(资源地域为同地域即可,本次引导默认选杭州) 在列表页面,单击创建实例,并完成创建。 创建完成后点击详情进入实例详情页; 在“Vhost 列表” 创建 “testamqpv”; 在“Queue 列表” ,选择 Vhost 为“testamqpv”,并创建 “testamqpq”; 3)创建 EventBridge 事件流任务   MNS TO MNS(A 实验可选) 本步骤将指导您如何通过控制台创建 EventBridge 事件流。 使用您自己的阿里云账号登录阿里云控制台,然后访问 EventBridge 控制台。[3] 注:第一次使用需开通。 单击“事件流”列表,并在列表创建任务 (资源地域为同地域即可,本次引导默认选杭州) 创建事件流名称为“testamqpmns2mns”,点击下一步; 指定事件源,事件提供方为“消息服务 MNS”,队列名称为“testmnsq”,点击下一步; 指定规则,规则部分可不做筛选,默认匹配全部,直接点击下一步; 注意:规则内容可根据需求自行指定,为降低难度本次实验默认投递全部,更多详情请查阅: 服务类型选择“消息服务 MNS”,队列名称选择“testmnsq2”,消息内容选择“部分事件”,点击创建 注意:消息内容可根据需求自行指定,本次实验默认投递 data 字段,更多详情请查阅: 创建完成后,可点击“启动”来启动事件流 4)创建 EventBridge 事件流任务 MNS TO RabbitMQ(B 实验可选) 本步骤将指导您如何通过控制台创建 EventBridge 事件流。 使用您自己的阿里云账号登录阿里云控制台,然后访问 EventBridge 控制台。[3]注:第一次使用需开通。 单击“事件流”列表,并在列表创建任务 (资源地域为同地域即可,本次引导默认选杭州) 创建事件流名称为“testamqpmns2rabbitmq”,点击下一步 指定事件源,事件提供方为“消息服务 MNS”,队列名称为“testmnsq”,点击下一步 指定规则,规则部分可不做筛选,默认匹配全部,直接点击下一步 注意:规则内容可根据需求自行指定,为降低难度本次实验默认投递全部,更多详情请查阅: 服务类型选择“消息队列 RabbitMQ 版本”,具体配置如下,点击创建 实例ID:选择创建好的RabbitMQ ID Vhost:选择“testamqpv” 目标类型:选择“Queue” Queue:选择“testamqpq” Body:选择“部分事件”,填写“$.data” MessageId:选择“常量”,填写“0” Properties:选择“部分事件”,填写“$.source” 注意:消息内容可根据需求自行指定,本次实验默认投递 data 字段,更多详情请查阅: 创建完成后,可点击“启动”来启动事件流 5)验证路由任务 向 MNS Source  “testmnsq ” 发送实验消息 点击下载 MNS SDK[4] 修改 sample.cfg 在 “sample.cfg ” 填写 AccessKeyId,AccessKeySecret,Endpoint 等信息 AccessKeyId,AccessKeySecret 可在阿里云 RAM 控制台[5]创建 Endpoint 即步骤 1 , MNS 公网接入点地址 AccessKeyId = xxxxxx AccessKeySecret = xxxxxxx Endpoint = http://xxxx.mns.cnhangzhou.aliyuncs.com 填完效果如下,保存 找到 sample 目录的“sendmessage.py” 示例 将循环参数调整为 200,并保存 (可选) 保存并运行 “python sendmessage.py testmnsq” python sendmessage.py testmnsq 在事件流控制台[6],分别点开 “testmnsq2”, “testamqpq” 查看详情转储详情。 注意:MNS Q 仅支持单订阅,不支持广播模式。故该测试需要将 MNS/RabbitMQ 两个实验,任选其一关停后进行实验。 如需广播模式,请创建 MNS Topic 资源。 A 链路实验结果: B 链路实验结果: 优势及总结 EventBridge 事件流提供端到端的消息路由能力,通过简单配置即可完成消息分发,消息同步,跨地域消息备份,跨产品消息同步等能力。具有运维简单,成本低,效率高,使用稳定等优势。同时使用 EventBridge 可以实现基础的数据过滤,数据脱敏等数据处理类能力。是消息路由场景下运维成本最低的解决方案。 相关链接 [1] 消息队列MNS版控制台 [2] 消息队列RabbitMQ版控制台 [3] EventBridge 控制台 [4] 点击下载 MNS SDK [5] 阿里云RAM 控制台 [6] 事件流控制台 活动推荐 阿里云基于 Apache RocketMQ 构建的企业级产品消息队列RocketMQ 5.0版现开启活动: 1、新用户首次购买包年包月,即可享受全系列 85折优惠! 了解活动详情:
作者:肯梦
#技术探索 #生态集成

2022年2月5日

技术盘点:消息中间件的过去、现在和未来
操作系统、数据库、中间件是基础软件的三驾马车,而消息队列属于最经典的中间件之一,已经有30多年的历史。其发展主要经历了以下几个阶段: 第一个阶段,2000年之前。80年代诞生了第一款消息队列是 The Information Bus,第一次提出发布订阅模式来解决软件之间的通信问题;到了90年代,则是国际商业软件巨头的时代,IBM、Oracle、Microsoft纷纷推出了自己的 MQ,其中最具代表性的是IBM MQ,价格昂贵,面向高端企业,如大型金融、电信等企业;这类商业MQ一般采用高端硬件,软硬件一体机交付,MQ本身的架构是单机架构。 第二阶段,2000~2007年。进入00年代后,初代开源消息队列崛起,诞生了JMS、AMQP两大标准,与之对应的两个实现分别为 ActiveMQ、RabbitMQ,开源极大的促进了消息队列的流行度,降低了使用门槛,逐渐成为了企业级架构的标配。相比于今天而言,这类MQ主要还是面向传统企业级应用,面向小流量场景,横向扩展能力比较弱。 第三阶段,2007~2018年。PC互联网、移动互联网爆发式发展。由于传统的消息队列无法承受亿级用户的访问流量和海量数据传输,诞生了互联网消息中间件,核心能力是全面采用分布式架构、具备很强的横向扩展能力,开源典型代表有 Kafka、RocketMQ,还有淘宝的 Notify。Kafka 的诞生还将消息中间件从Messaging领域延伸到了 Streaming 领域,从分布式应用的异步解耦场景延伸到大数据领域的流存储和流计算场景。 第四阶段,2014~至今。IoT、云计算、云原生引领了新的技术趋势。面向IoT的场景,消息队列开始从云内服务端应用通信,延伸到边缘机房和物联网终端设备,支持MQTT等物联网标准协议也成了各大消息队列的标配。 随着云计算的普及,云原生的理念深入人心,各种云原生代表技术层出不穷,包括容器、微服务、Serverless、Service Mesh、事件驱动等。云原生的核心问题是如何重新设计应用,才能充分释放云计算的技术红利,实现业务成功最短路径。 消息队列本身作为云计算的PaaS服务之一,要进一步发挥“解耦”的能力,帮助业务构建现代化应用,这里最关键的一个能力演进是Eventing的演进。通过将消息升华为“事件”,提供面向标准 CloudEvent 的编排过滤、发布订阅等能力构建更大范围的解耦,包括云服务事件和业务应用的解耦、跨组织SaaS业务事件的解耦、遗留应用和现代化应用的解耦等,同时事件驱动也是天然符合云计算 Serverless 函数计算的范式,是应用 Serverless 化演进的催化剂。 云原生对于消息中间件而言,还有另一层含义就是消息队列自身架构的云原生化演进,如何充分发挥云的弹性计算、存储、网络,让自己获得更强的技术指标和 Serverless 弹性能力。 消息中间件在技术上有哪些进展与突破? 阿里云 MQ 是基于 RocketMQ 打造的一站式消息服务,以 RocketMQ 作为统一内核,实现业界标准、主流的消息协议,包括MQTT、Kafka、RabbitMQ、AMQP、CloudEvent、HTTP等,满足客户多样化场景诉求。为了提高易用性,我们分别对不同的协议进行了产品化,以独立产品的模式提供消息服务(如阿里云RabbitMQ、阿里云Kafka),开箱即用、免运维、完备的可观测体系,帮助开源客户无缝迁云。 在经历数万企业客户多样化场景的持续打磨,数年的超大规模云计算的生产实践,我们的内核RocketMQ逐渐往一体化架构和云原生架构演进。 1. 一体化架构 微服务、大数据、实时计算、IoT、事件驱动等技术潮流,不断的扩展消息的业务边界,业界有不同的消息队列满足不同的业务场景,比如RabbitMQ侧重满足微服务场景,Kafka则是侧重于满足大数据、事件流场景,EMQ则是满足了IoT垂直领域场景。而随着数字化转型的深入,客户的业务往往同时涉及交叉场景,比如来自物联网设备的消息、或者微服务系统产生的业务消息要进行实时计算,如果是引入多套系统,会带来额外的机器、运维、学习等成本。 在过去“分”往往是技术实现的妥协,而现在“合”才是用户的真正需求。RocketMQ 5.0基于统一Commitlog扩展多元化索引,包括时间索引、百万队列索引、事务索引、KV索引、批量索引、逻辑队列等技术。在场景上同时支撑了RabbitMQ、Kafka、MQTT、边缘轻量计算等产品能力,真正实现了“消息、事件、流”,“云边端”一体化架构。 2. 云原生架构   云原生架构是指云上原生的架构,云计算是云原生的“源动力”,脱离了云计算谈云原生如同纸上谈兵。RocketMQ 过去几年正是立足于阿里云超大规模的云计算生产实践,帮助数万企业完成数字化转型的经验中吸取养分,从而完成互联网消息中间件到云原生消息中间件的进化。这也是 RocketMQ 和其他消息中间件最大的区别,他是实践出来的云原生架构,下面我们盘点一下 RocketMQ 在云原生架构的关键技术演进。 RocketMQ 是 2011 年诞生于淘宝核心电商系统,一开始是定位于服务集团业务,面向单一超大规模互联网企业设计。原来的架构并不能很好的满足云计算的场景,有不少的痛点,比如重型 SDK,客户端逻辑复杂、多语言 SDK 开发成本高、商业特性迭代慢;弹性能力差,计算存储耦合、客户端和物理队列数耦合、队列数无法扩展到百万级、千万级;而其他主流的开源消息项目也同样未进行云原生架构的转型,比如 RabbitMQ 单队列能力无法横向扩展、Kafka 弹性扩容会面临大量的数据拷贝均衡等,都不适用于在公共云为大规模客户提供弹性服务。 为此,RocketMQ 5.0 面向云计算的场景进行重新设计,期望从架构层面解决根本性问题,对客户端、Broker到存储引擎全面升级: 客户端轻量化。RocketMQ 5.0 SDK 把大量逻辑下沉到服务端,代码行数精简三分之二,开发维护多语言 SDK 的成本大幅度降低;轻量的 SDK 更容易被 Service Mesh、Dapr等云原生代表技术集成。 可分可合的存算分离架构。用户根据不同的场景诉求,既可以同一进程启动存储和计算的功能,也可以将两者分开部署。分开部署后的计算节点可以做到“无状态”,一个接入点可代理所有流量,在云上结合新硬件内核旁路技术,可以降低分离部署带来的性能及延迟问题。而选择“存储计算一体化”架构,则具备“就近计算”的优势,性能更优。在云上多租、多VPC复杂网络、多协议接入方式的场景下,采用存储计算分离模式能够避免后端存储服务直接暴露给客户端,便于实现流量的管控、隔离、调度、权限管理、协议转换等。 但是有利必有弊,存算分离也同时带来了链路变长、延迟增大、机器成本上升等问题,运维也没得到简化,除了要运维有状态存储节点外,还要多运维无状态计算节点。其实在大多数简单消息收发场景,数据链路基本上就是写Log、读Log,无复杂计算逻辑(计算逻辑和数据库相比太简单),这个时候优选存储计算一体化架构,简单够用、性能高、延迟低。特别是在大数据传输场景下,存算一体能够极大降低机器及流量成本,这个从 Kafka 的架构演进也可以得到印证。总的来说不要为了存算分离而分离,还是要回归客户、业务场景的本质诉求。 弹性存储引擎。面向 IoT 海量设备、云上大规模小客户场景,我们引入 LSM 的 KV 索引,实现单机海量队列的能力,队列数量可以无限扩展;为了进一步释放云存储的能力,我们实现分级存储,消息存储时长从3天提高到月、年级别,存储空间可以无限扩展,同时还分离了冷热数据,冷数据存储成本降低了80%。 Serverless化。在老架构里面,客户感知物理队列,物理队列绑定固定存储节点,强状态。Broker、客户端、物理队列的扩缩容互相耦合,负载均衡粒度是队列级,对Serverless的技术演进很不友好。为了实现极致弹性 Serverless,RocketMQ 5.0 对逻辑资源和物理资源做进一步的解耦。 在 Messaging/无序消息的场景,客户指定 Topic 进行消息无序收发,新架构对客户端屏蔽队列概念,只暴露逻辑资源 Topic。负载均衡粒度从队列级到消息级,实现了客户端的无状态化,客户端、服务端弹性伸缩解耦。 在 Streaming/顺序消息的场景,客户端需要指定 Topic 下的某个队列(也称分区)进行消息顺序收发。在新架构里,对客户端屏蔽物理队列,引入逻辑队列概念,一个逻辑队列通过横向分片和纵向分段,分散在不同的物理存储节点。横向分片解决了高可用问题,同一个逻辑队列的多个分片多点随机可写,基于 Happen before 的原理保序,秒级 Failover,无需主备切换;纵向分段,解决逻辑队列的扩容问题,通过多级队列映射,实现 0 数据迁移的秒级扩容,逻辑资源和物理资源的弹性伸缩解耦。   如何看待消息领域生态玩家? 在云原生、IoT、大数据的趋势引导下,消息成为现代化应用架构的刚需,使用场景更加广泛,可应用于微服务的异步解耦、事件驱动、物联网设备数据上下行、大数据流存储、轻量流计算等场景。客户需求旺盛、市场活跃,吸引了不少厂商加入角逐。 从好的角度来看,厂商的充分竞争,会进一步激活创新,培养更多用户,共同做大消息的市场,用户看起来也有更多的选择; 从坏的角度来看,未来部分竞争失利的消息队列会进入停滞期、下线期,用户的应用就会面临迁移大改造和稳定性风险,所以建议用户在满足自身业务需求的情况下,尽可能选择标准接口、协议的方式接入,或者直接使用业界事实标准的消息队列。 消息中间件未来的发展趋势是什么?   随着 IoT、5G 网络的持续发展,数据量增速28%,预计到2025年物联网设备将达到 400 亿台,进入万物互联的时代。物联网时代的消息存储量和计算量会爆发式增长,消息系统将面临巨大的成本压力。未来消息系统,需要深挖新硬件的红利,比如持久内存、DPU等技术,采用软硬结合的方式深度优化,将消息的存储计算成本进一步降低。 IoT时代还有另外一个很重要的趋势是边缘计算,Gartner 预计到 2025 年,75%的数据将在传统数据中心或云环境之外进行处理,消息系统需要进一步轻量化、降低资源消耗以适应边缘计算环境。这也意味着,消息中间件的一体化架构,要具备良好的插件化设计,能够根据场景的特点实现多形态输出。比如公共云的形态可以和公共云的基础设施深度集成,充分利用云盘、对象存储增强存储能力,集成日志服务、应用监控等服务提升可观测能力;而边缘计算的形态则是以最小的资源代价输出核心存储、轻量计算的能力,简单够用即可。 近几年云计算高速发展,得益于全球范围内大量企业在进行数字化转型,通过业务在线化、业务数据化、数据智能化来提升企业竞争力。数据化转型也伴随着商业思维的转型,越来越多的企业采用“事件驱动”的模式来构建商业逻辑和数字化系统。 Gartner预测,未来超过60%的新型数字化商业的解决方案会采用“事件驱动”模式,从业务角度看,“事件驱动”的模式能够帮助企业实时响应客户,抓住更多的商业机会,创造增量价值;从技术角度看,“事件驱动”的架构,能够以动态、灵活、解耦的方式来链接跨组织、跨环境的异构系统,天然适合用于构建大型的跨组织数字化商业生态。 为了应对这个趋势,Messaing 往 Eventing 演进,出现了 EventBridge (EventBroker)的产品形态。在 EventBridge 里,“事件”这个概念成为一等公民,事件的发布者和订阅者不耦合任何一种具体的消息队列SDK和实现。EventBroker 围绕标准的 CloudEvent 规范构建更加泛化的发布订阅模式,能够链接一切跨组织、跨环境的异构事件源和事件处理目标。 目前以“事件驱动”构建的数字化商业生态才刚起步,未来 EventBridge 将围绕事件这一抽象层次实现更强大的能力,比如事件的全链路可观测、事件分析计算、低代码开发等特性,帮助企业全面落地云时代的“事件驱动”架构。 作者介绍: 林清山(花名:隆基),阿里云资深技术专家,阿里云消息产品线负责人。国际消息领域专家,致力于消息、实时计算、事件驱动等方向的研究与探索,推进 RocketMQ 云原生架构、超融合架构的演进。 活动推荐 阿里云基于 Apache RocketMQ 构建的企业级产品消息队列RocketMQ 5.0版现开启活动: 1、新用户首次购买包年包月,即可享受全系列 85折优惠! 了解活动详情:
作者:林清山(花名:隆基)
#技术探索

2021年12月15日

重新定义分析 - EventBridge实时事件分析平台发布
对于日志分析大家可能并不陌生,在分布式计算、大数据处理和 Spark 等开源分析框架的支持下,每天可以对潜在的数百万日志进行分析。 事件分析则和日志分析是两个完全不同的领域,事件分析对实时性的要求更高,需要磨平事件领域中从半结构化到结构化的消息转换管道,实现查询检索,可视化等功能。但是目前针对流式的事件做分析的可用工具非常少,这对于期望使用Serverless架构或 EDA(事件驱动)架构的开发者会非常不便。(更多 EDA 架构介绍参考 :) 基于事件的特征,无法追溯事件内容,无法跟踪事件流转,无法对事件做可视化分析成为了事件驱动架构演进的绊脚石。为了解决事件领域中针对流式事件做分析的难题,EventBridge 近日发布了针对事件/消息领域的全新分析工具EventBridge 实时事件分析平台。下面简要对 EventBridge 实时事件分析平台的内容进行介绍。 EventBridge 实时事件分析平台简介_ EventBridge 实时事件分析平台依托基于事件的实时处理引擎,提供数值检索、可视化分析、多组态分析、事件轨迹、事件溯源和 Schema 管理等能力。EventBridge 实时事件分析平台具有无入侵、无需数据上报,低成本,操作快捷等特点,通过简单的引导式交互,即可快速实现基于事件的流式查询与分析。 EventBridge 实时事件分析平台依托基于事件的实时处理引擎,提供数值检索,可视化分析,多组态分析,事件轨迹,事件溯源,Schema 管理等能力。EventBridge 实时事件具有无入侵,无需数据上报,低成本,操作快捷等特点,通过简单的引导式交互,即可快速实现基于事件的流式查询与分析。 核心功能 多场景支持 目前市面上比较流行的是事件查询平台,但是分析和查询还是有些本质区别,分析基于查询,但是查询并不是分析的全部。 EventBridge 构建了一套完整的事件工具链,帮助开发,运维,甚至运营团队更高效的使用分析工具,统一在一个分析平台上无缝整合全部事件,提供高效、可靠、通用的事件分析能力。 Serverless 领域:得益于 Serverless 架构的推广,事件驱动被更多用在企业核心链路。无服务器的定义是不必管理任何基础设施,但是无服务器的不透明且难以调试却是整个架构必需解决的痛点,当我们配置完触发器后不会知道什么数据在什么时刻触发了函数,触发链路是否异常。EventBridge 事件分析能力将彻底解决 Serverless触发数据黑箱的问题,让所有事件触发都清晰可见。 微服务领域:微服务在现代开发架构中比较常见,该架构由小型、松耦合、可独立部署的服务集合而成,这导致微服务架构很难调试,系统中某一部分的小故障可能会导致大规模服务崩溃。很多时候不得不跳过某些正常服务来调试单个请求。EventBridge 事件分析可将全部链路微服务消息通过事件 ID 染色做有效追踪与排障,帮助微服务做可视化排障。 消息领域:在传统消息领域,消息 Schema 管理、消息内容检索一直是无法解决的难题,大部分情况下需要增加订阅者来对消息做离线分析。EventBridge 事件分析平台提供消息 Schema 管理与消息内容查询能力,为消息可视化提供更完全的解决方案。 云产品领域:云产品在极大程度降低了企业对基础设施建设的复杂性,但同样带来了诸多问题,以 ECS 为例,很多情况会因系统错误或云盘性能受损而触发故障类事件,这类事件通常会涉及到周边产品(比如 ACK 等),捕获全部云上事件做基础排障的挑战性比较大。EventBridge 支持全部云服务事件无缝接入,更大程度降低由云产品变更导致的运维故障。 EventBridge 提供更高效、通用的事件分析平台,基于该平台可以解决大部分场景对事件分析、事件查询、事件轨迹的诉求。 开箱即用 支持提供 Schema 管理,数值检索,可视化分析,多组态分析,事件轨迹,事件溯源等核心能力,无需额外部署,即开即用。 数值检索:提供基础数值检索能力,支持键入 key,value ,= ,!= , exists ,AND,OR 等参数,满足事件检索场景的基本诉求。 可视化分析:提供 GROUP BY,ORDER BY 等可视化分析能力,支持多组态,多图表,多维度分析能力。 链路追踪:提供事件轨迹能力,还原事件整体链路状态。帮助开发者快速排障,快速定位链路问题。 低成本接入 EventBridge 支持以事件总线(EventBus)形式接入,分为云服务事件总线和自定义事件总线。云服务总线支持几乎全部阿里云产品事件,无缝支持云服务事件接入事件分析平台;自定义事件总线支持 RocketMQ、Kafka 或其他自定义事件接入(当前版本仅支持少量云服务事件)。 整体接入流程较为简单,对原有业务入侵小,可随时关闭或开启事件分析,同时实现在线配置,且具备实时生效功能。 总结_ EventBridge 提供更便捷高效的事件分析工具,可以帮助开发人员简单定义查询条件,及时进行可视化的事件内容分析。 活动推荐 阿里云基于 Apache RocketMQ 构建的企业级产品消息队列RocketMQ 5.0版现开启活动: 1、新用户首次购买包年包月,即可享受全系列 85折优惠! 了解活动详情:
作者:肯梦
#技术探索 #生态集成

2021年10月28日

阿里云消息队列 RocketMQ 5.0 全新升级:消息、事件、流融合处理平台
从“消息”到“消息、事件、流”的大融合 消息队列作为当代应用的通信基础设施,微服务架构应用的核心依赖,通过异步解耦能力让用户更高效地构建分布式、高性能、弹性健壮的应用程序。 从数据价值和业务价值角度来看,消息队列的价值不断深化。消息队列中流动的业务核心数据涉及集成传输、分析计算和处理等不同环节与场景。伴随着不断演进,我们可以预见消息队列势必在数据通道、事件集成驱动、分析计算等场景不断产生新价值,创造新的“化学反应”。 RocketMQ 诞生于阿里巴巴内部电商系统,发展至今日,其核心架构经历了多次关键演进: 早在 2007 年,淘宝电商系统做服务化拆分的时候,就诞生了第一代消息服务 Notify,这是 RocketMQ 最早雏形。Notify 采用了关系型数据库作为存储,使用推模式。在阿里淘宝这种高频交易场景中,具有非常广泛地应用。 在 20072013 年期间,随着阿里集团业务发展,不仅需要交易场景异步调用,同时需要支持大量传输埋点数据、数据同步。此时,内部衍生出 MetaQ 以及 RocketMQ3.0 版本,这两个版本开始探索自研存储引擎,采用了自研专有消息存储,支持了单机海量 Topic,并前瞻性地去除了 Zookeeper 等组件的外部依赖。在十年后的今天,我们看到去各种 keeper 已成为整个消息领域的发展主流。 经历了前三代的内部业务打磨后,阿里巴巴积极参与开源并将 RocketMQ3.0 贡献到开源社区,并于 2017 年从 Apache 孵化器毕业,成为中国首个非 Hadoop 生态体系的 Apache 社区顶级项目。此后,RocketMQ 也开始服务于阿里云企业客户。秉承开源、商业、内部三位一体发展策略,18 年发布的 4.x 版,在高可靠低延迟方面重点优化,构建了全新的低延迟存储引擎和多场景容灾解决方案、并提供了丰富的消息特性。这也使得 RocketMQ 成为金融级的业务消息首选方案。 上个月社区发布了 RocketMQ5.0preview 版,正式宣告 5.0 的到来。RocketMQ5.0 将不再局限于消息解耦的基本场景,更是通过统一内核、存储的优势,提供消息、事件、流一体化的处理能力。 回顾 RocketMQ 发展的十余年,良好的社区环境和商业支持使得大量企业开发者可以很方便的跟进业务特点和诉求进行选型和验证。在社区活跃影响力方面,RocketMQ 社区项目收获 15000+Star,活跃的贡献者有 400+ 位,多语言、生态连接等周边活跃项目 30+ 个,深受社区开发者欢迎。在应用规模方面,RocketMQ 作为金融级业务消息方案,积累了互联网游戏、在线教育、金融证券、银行、政企能源、汽车出行等众多行业数以万计的企业客户。同时,在阿里巴巴内部担负业务核心链路,每天流转万亿级消息流量,扛过了历届双十一的零点峰值。在行业评测方面,RocketMQ 也多次斩获大奖。 官宣:阿里云新一代 RocketMQ “消息、事件、流”融合处理平台 今天发布阿里云消息队列 RocketMQ 版 5.0,我们称之为一站式“消息、事件、流”融合处理平台。 新版本核心诞生两大新亮点,首先是消息核心场景的扩展和布局,RocketMQ 5.0 不再局限于消息解耦场景,将全新布局事件驱动和消息流式处理场景;其次则是一站式融合处理的技术架构和趋势。 “消息、事件、流”一站式融合处理的技术架构可以实现一份消息存储,支持消息的流式计算、异步投递、集成驱动多种场景,极大地降低业务人员运维多套系统的技术复杂度和运维成本。可以说,无论是微服务的指令调用、异步通知,还是 CDC 变更日志、行为埋点数据,亦或是资源运维、审计事件,统一的 RocketMQ5.0 产品栈都能统一处理。 重大发布一: RocketMQ 基础架构全新升级 首先,最重要的升级是阿里云 RocketMQ 的技术架构全面焕新。 全新的 RocketMQ5.0 版将通用的存储逻辑下沉,集中解决消息存储的多副本、低延迟、海量队列分区等技术问题,将上层的消息处理和剥离出完全的无状态计算层,主要完成协议适配、权限管理、消费状态、可观测运维体系支持。得益于存算分离的架构设计,从 SDK 接入到线上运维全链路带来全面提升: 1. 轻量版 SDK 的开放和全链路可观测系统的提升:同时支持 4.x 通信协议和全新的 gRPC 通信协议,并内置 OpenTelemetry 埋点支持,新版本 SDK 新增了 10 余个指标埋点。 2. 消息级负载均衡:新版本 SDK 不再参与实际存储队列的负载均衡,消息负载均衡将更加轻量,以单条消息为调度最小单元。 3. 多网络访问支持:新版本支持单一实例同时暴露公网、内网等访问形式,方便客户多网络接入访问。 4. 海量分级存储:新版本开放分级存储历史消息保存能力,消息低成本无大小限制,最长保存 30 天。冷热数据进行分离设计,极大降低消费历史消息对实例的性能影响。 重大发布二: RocketMQ Streaming 云上最佳实践——消息ETL 消息基础架构的能力提升之外,阿里云 RocketMQ 在 Streaming 流式处理场景推出了轻量级消息 ETL 功能。 用户在数据库变更、终端数据上报、后台埋点日志等场景产生的消息,典型的消费场景就是数据清洗转化,同时再存储到外部的存储和离线分析、在线分析系统中。传统实现方案需要搭建 Flink 等重量级实时计算服务或者自建消费应用做消息处理。而使用商业版 RocketMQ ETL 功能,简单控制台配置即可实现消息的清洗和转化。RocketMQ ETL 功能有三大优势: 1. 轻量无依赖:作为阿里云消息原生功能,使用时不需要部署外部计算服务或消费程序,方案更轻量。 2. 开发门槛低:内置常见清洗转化模板,满足绝大多数消息内容处理需求,并支持用户快速编写自定义函数来支持特殊的业务逻辑。整体开发成本非常低,1 小时即可完成业务上线。 3. Serverless 弹性:无需预先估算容量,采取 Serverless 无服务器模式,实现按需弹性伸缩。 重大发布三: EDA 云上最佳实践——事件中心 EventBridge 本次 RocketMQ 最后一个发布点是在事件驱动的业务场景的布局和演进。早在 2018 年,Gartner 评估报告将 EDA(EventDrivenArchitecture) 列为十大战略技术趋势之一,事件驱动架构将成为未来微服务主流。我们首先下一个定义: 事件驱动其本质是对消息驱动的再升级,是企业IT架构深度演进的下一个必然阶段。 事件驱动架构和消息驱动架构的区别和关联主要集中于以下三点: 1. EDA 更加强调深层次解耦:消息驱动是同一业务、组织系统内不同组件之间在技术架构层面的调用解耦,其信息封装和处理都是有预期、预定义的。事件驱动适配是更宽泛的业务、组织系统,基于事件的解耦上下游之间无需有预期和行为定义,上下游统一遵循标准化的规范,这是更深度的解耦。 2. EDA 更加强调连接能力:消息驱动更多是单一系统内的调用,而事件驱动往往会涉及到不同的地域、账户主体以及三方 SaaS 的协同,事件驱动的一大特征就是生态的强连接能力。 3. EDA 更加强调 Serverless 低代码开发:类比于消息和微服务的协同关系,未来业务架构 Serverless 化的大趋势会推动业务开发模式逐步转向低代码配置化。事件驱动的另一大特征就是低代码开发,基于丰富的工具能力,业务侧不需要像消息驱动一样编写大量的生产消费代码。 因此,阿里云统一事件中心 EventBridge 产品带来如下能力: 1. 统一标准化的事件集成生态:作为阿里云事件中心,集成 80 余款云产品的业务事件,支持 800 多种事件类型,用户使用 EventBridge 可以一次性管理所有云产品资源的变更、操作使用事件,避免对接多个产品接口的重复性劳动。 2. 全球事件互通网络:贯彻事件驱动强连接的属性能力,本次发布了全球事件互通网络,首批支持国内五大地域事件互通。企业客户简单配置即可实现跨账号、跨地域、跨网络的事件聚合和流转。 3. Serverless 低代码开发:内置十余种事件目标和处理模板,涵盖了大多数业务场景,客户简单配置、低代码,无需部署服务即可完成事件的驱动和处理。 面向未来: 坚定推动“消息、事件、流”大融合的发展 RocketMQ5.0 的发布标志着阿里云消息从消息领域正式迈向了“消息、事件、流”场景大融合的新局面。未来阿里云消息产品的演进也将继续围绕消息、事件、流核心场景而开展。消息基础架构本身也必将步伐不断,继续朝着 Serverless 弹性、强容灾能力、可观测免运维方向推进,给客户带来高性能、高可靠、强容灾的高 SLA 服务;并在 Streaming 的场景会基于客户业务诉求,联合生态产品持续推出更多的消息处理计算服务;打造面向未来的企业集成模式,联合生态伙伴和开源社区大力推动事件驱动进一步发展。 活动推荐 阿里云基于 Apache RocketMQ 构建的企业级产品消息队列RocketMQ 5.0版现开启活动: 1、新用户首次购买包年包月,即可享受全系列 85折优惠! 了解活动详情:
#技术探索

2021年10月12日

EDA 事件驱动架构与 EventBridge 二三事
当下比较成功的企业已然认识到,要想最大限度提升运营效率和客户体验,务必将业务和技术两方面的举措紧密结合起来。运营事件或业务形势的变化是时下众多企业关注的焦点,这些变化能够为企业领导者带来切实有用的信息,而架构设计的主旨恰恰是从客户联系人、交易、运营等方面的信息中获取洞见,两者相辅相成。传统技术历来对企业从事件中获取洞见的速度有着诸多限制,比如用于记录、收集和处理此类事件的批处理 ETL(提取、转换、加载)。 事件驱动型架构 (EDA) 方兴未艾,作为一种 Serverless 化的应用概念对云原生架构具有着深远影响。当我们讨论到一个具体架构时,首当其冲的是它的发展是否具有技术先进性。这里从我们熟悉的 MVC 架构,SOA 架构谈起,聊一聊关于消息事件领域的历史与发展趋势。 消息事件领域的发展趋势 早在 2018 年,Gartner 评估报告将 EventDriven Model 列为 10 大战略技术趋势之一,事件驱动架构(EDA)将成为未来微服务的主流,并做出以下断言: 到 2022 年,事件通知的软件模型将成为超过 60% 的新型数字化商业的解决方案; 到 2022 年,超过 50% 的商业组织将参与到事件驱动的数字化商业服务的生态系统当中; George Santayana 在《 The Life of Reason》曾提到, Those who fail to learn History are doomed to repeat it.(不懂历史的人注定会重蹈覆辙)。我们以史为鉴,来看看为什么会架构会演进到事件驱动。 架构本身没有优劣之分,它本身就是一组技术决策,决定后续项目的所有功能开发(框架,编码规范,文档,流程….),这里聊聊为什么会引入某些框架,这个框架解决了软件开发中的什么问题。 单体架构:在单节点服务中,单体应用的所有模块都封装在单个进程运行,通信通过相同堆栈调用完成。这种模式下非常容易导致结构和关系不明确,难以对系统进行更改和重构。就像一个不透明的,粘稠的,脆弱的,僵硬的 Big Ball of Mud! 分层架构:在经典的分层架构中,层以相当谨慎的方式使用。即一个层只能知道它下方层的数据。在随后的实际应用中,更多的方式是一个层可以访问它下面的任何层。分层架构解决了单体架构的的逻辑分离问题,每一层都可以被等效替换,层区分也更加标准化,同时一个层可以被几个不同/更高级别的层使用。当然,层也有比较明显的缺点,层不能封装掉一切,比如添加到UI的某个字段,可能也需要添加到DB,而且额外多余的层会严重损害系统性能。 MVC 架构:MVC 架构产生的原因其实很简单,随着业务系统的复杂性增加,之前所谓“全栈工程师”已经不适用大部分场景。为了降低前端和后台的集成复杂性,故而开始推广 MVC 架构。其中,Model 代表业务逻辑,View 代表视图层比如前端UI的某个小组件,Controller 提供 View 和 Model 的协调比如将用户某项操作转为业务逻辑等。这里还有很多扩展架构,譬如 ModelViewPresenter ,ModelViewPresenterViewModel,ResourceMethodRepresentation,ActionDomainResponder 。 EBI 架构:即 Entity,Boundary(接口),Interactor(控制)。EBI架构将系统边界视为完整连接,而不仅仅是视图,控制器或接口。EBI 的实体代表持有数据并结束相关行为的实际实体,很类似阿里云的 POP API。EBI 主要还是后端概念,他是与 MVC 相辅相成的。 洋葱架构:洋葱架构是一种低耦合,高内聚的架构模型。所有的应用程序围绕独立的对象模型构建,内层定义接口外层实现接口,耦合方向向中心内聚,所有代码都可以独立与基础设施进行编译和运行。 SOA 架构:SOA 是 Service Orientated Architure 的缩写,即面向服务架构。表示每一个功能都是通过一个独立的服务来提供,服务定义了明确的可调用接口,服务之间的编排调用完成一个完整的业务。其实这个架构也是目前架构中最成熟的,日常使用最多的架构模式。 什么是 EDA 架构 我们聊完之前全部的架构趋势后,再回过头看看什么是 EDA 架构。 EDA 事件驱动架构( EventDriven Architecture ) 是一种系统架构模型,它的核心能力在于能够发现系统“事件”或重要的业务时刻(例如交易节点、站点访问等)并实时或接近实时地对相应的事件采取必要行动。这种模式取代了传统的“ request/response ”模型,在这种传统架构中,服务必须等待回复才能进入下一个任务。事件驱动架构的流程是由事件提供运行的。 上图其实很好的解释了 EDA 架构的模型,但是其实还不够明确。所以,这里我们和单体架构一起对比看看他们之间差异。 在如上对比图中,我们其实可以较为清楚看到它与传统架构的区别。在一般传统架构中,创建订单操作发生后,一系列的操作其实都是通过一个系统完成的。而事件驱动的概念则是将全部操作都转换为 “事件” 概念,下游通过捕获某个 “事件” 来决定调用什么系统完成什么样的操作。 总结来看,事件驱动其实是将比较重要的业务时刻封装成“事件”,并通过某个 EventBus 将事件路由给下游系统。 我们了解了 EDA 架构的整个处理过程,但是还没解决这个所谓的“EventBUS”到底是啥样。 上图就是事件驱动的核心逻辑架构。是不是非常像某个传统 MQ?别着急,下面我会讲到这个架构的复杂部分。讲完 EventBus,我们回过头来看“事件”,刚刚介绍中比较重要部分其实是将操作转换为某类事件进行分发。那这的事件我们怎么定义呢? 简单来看,其实事件就是状态的显著变化,当用户采取特定行动时触发。以 4S 店售卖汽车为例: 当客户购买汽车并且其状态从 For Sale 变为 Sold 是一个事件。 成功交易后,从帐户中扣除金额是一个事件。 单击预订试驾后,从将预约信息添加到指定用户就是一个事件。 每个事件都可能触发一个或多个选项作为响应。 关于事件其实云原生 CNCF 基金会在 2018 年托管了开源 CloudEvents 项目,该项目旨在用统一和规范的格式来描述事件,来加强不同的服务、平台以及系统之间的互操作性。在该项目定义下,通用的事件规范是这样的: 事件主要由 Json 体构成,通过不同字段描述发生的事件。 EDA 架构的落地实践思考 在开始介绍落地实践时,我们先来看一个经典的 EDA 架构模型: 这是一个非常经典 EDA 订单架构,该架构主要使用了 EventBridge 和 FC 函数计算(如果不太熟悉 FaaS 的同学可以把 FC 节点当作 ECS 或 K8s 的某个 POD 节点),通过事件驱动各个业务进行协作。 所以这块的中心节点(EventBridge)其实有三个比较重要的能力: 1. For Event Capturing(事件收集):具备采集事件的能力 2. For Routing(事件路由):通过事件内容将事件路由分发至于下游的能力的 3. For Event Processing(事件过滤/替换):对事件进行脱敏或初步过滤&筛选的能力 通常情况下,要实现这三个能力是比较困难的,比如:Event Capturing 可能需要熟悉 Dell Boomi, Snaplogic, MuleSoft, Dataflow, Apache Apex 等,Routing 部分可能通过 RocketMQ,RabbitMQ, ActiveMQ, Apache Kafka ,Event Processing 需要了解 Apache Storm, Apache Flink 。所以之前讲的逻辑架构其实非常理想,要想实现完成的 EDA 事件驱动还需要包括这些核心能力。   其实,从刚刚的架构中我们也能窥探到一些信息,EDA 架构其实看起来没有那么简单,那它有何优劣呢?下面我就简单罗列下 EDA 架构在实践中的优势: 松耦合:事件驱动架构是高度松耦合且高度分布式的架构模型,事件的创建者(来源)只知道发生的事件,并不知道事件的处理方式,也关心有多少相关方订阅该事件。 异步执行:EDA 架构是异步场景下最适合的执行工具,我们可以将需要事件保留在队列中,直到状态正常后执行。 可扩展性:事件驱动架构可以通过路由&过滤能力快速划分服务,提供更便捷的扩展与路由分发。 敏捷性:事件驱动架构可以通过将事件分发至任何地方,提供更敏捷高效的部署方案。 当然,劣势也很明显: 架构复杂:事件驱动架构复杂,路由节点多,系统结成复杂,功能要求多。 路由分发难:事件路由及分发难,灵活的事件路由需要依赖强大的实时计算能力,对整体分发系统要求较高。 无法追踪:事件追踪是整个 EDA 架构保证,EDA 架构中往往很难追踪到事件处理状态,需要大量的定制化开发。 可靠性差:事件驱动由于需要多系统集成,可靠性通常较差,且交付无法保障。   阿里云 EventBridge 如何解决 EDA 场景下的困境 针对 EDA 场景下面临的这些问题,阿里云推出了 EventBridge,一款无服务器事件总线服务,其使命是作为云事件的枢纽,以标准化的 CloudEvents 1.0 协议连接云产品和应用,应用和应用,提供中心化的事件治理和驱动能力,帮助用户轻松构建松耦合、分布式的事件驱动架构;另外,在阿里云之外的云市场上有海量垂直领域的 SaaS 服务,EventBridge 将以出色的跨产品、跨组织以及跨云的集成与被集成能力,助力客户打造一个完整的、事件驱动的、高效可控的上云体验。并针对 EDA 困境提供了针对性的解决方案。 架构复杂:提供业内通用的  Source ,Buses,Rules,Targets  模块管理能力,同时支持 EventBus 和 EventStream 两种模式。大幅度降低事件驱动架构难度。 路由分发:EventBridge 通过事件规则驱动,支持 8 大事件模式,4 重转换器,满足路由分发的全部诉求。 无法追踪:独家提供事件追踪能力,事件分析/查询能力。为用户完善整体事件链路。 可靠性差:支持 DLQ/ 重试机制,大幅度保证由于用户下游系统导致的事件故障与延迟。同时,在此基础上 EventBridge 支持 82 种阿里云产品,847 种事件类型。 阿里云 EventBridge 更多场景介绍 1. 经典 EDA 事件驱动:事件总线(EventBridge)最重要的能力是通过连接应用程序,云服务和 Serverless 服务构建 EDA(Eventdriven Architectures) 事件驱动架构,驱动应用与应用,应用与云的连接。 2. 流式 ETL 场景:EventBridge 另一个核心能力是为流式的数据管道的责任,提供基础的过滤和转换的能力,在不同的数据仓库之间、数据处理程序之间、数据分析和处理系统之间进行数据同步/跨地域备份等场景,连接不同的系统与不同服务。 3. 统一事件通知服务:EventBridge 提供丰富的云产品事件源与事件的全生命周期管理工具,您可以通过总线直接监听云产品产生的数据,并上报至监控,通知等下游服务。  目前事件总线免费公测,点击下方链接,立即体验! 活动推荐 阿里云基于 Apache RocketMQ 构建的企业级产品消息队列RocketMQ 5.0版现开启活动: 1、新用户首次购买包年包月,即可享受全系列 85折优惠! 了解活动详情:
作者:肯梦
#技术探索 #事件驱动架构

2021年6月28日

解读 RocketMQ 5.0 全新的高可用设计
高可用架构演进背景 在分布式系统中不可避免的会遇到网络故障,机器宕机,磁盘损坏等问题,为了向用户不中断且正确的提供服务,要求系统有一定的冗余与容错能力。RocketMQ 在日志,统计分析,在线交易,金融交易等丰富的生产场景中发挥着至关重要的作用,而不同环境对基础设施的成本与可靠性提出了不同的诉求。在 RocketMQ v4 版本中有两种主流高可用设计,分别是主备模式的无切换架构和基于 Raft 的多副本架构(图中左侧和右侧所示)。生产实践中我们发现,两副本的冷备模式下备节点资源利用率低,主宕机时特殊类型消息存在可用性问题;而 Raft 高度串行化,基于多数派的确认机制在扩展只读副本时不够灵活,无法很好的支持两机房对等部署,异地多中心等复杂场景。RocketMQ v5 版本融合了上述方案的优势,提出 DLedger Controller 作为管控节点(中间部分所示),将选举逻辑插件化并优化了数据复制的实现。 如何实现高可用系统 副本组与数据分片 在 PrimaryBackup 架构的分布式系统中,一份数据将被复制成多个副本来避免数据丢失。处理相同数据的一组节点被称为副本组(ReplicaSet),副本组的粒度可以是单个文件级别的(例如 HDFS),也可以是分区级 / 队列级的(例如 Kafka),每个真实存储节点上可以容纳若干个不同副本组的副本,也可以像 RocketMQ 一样粗粒度的独占节点。独占能够显著简化数据写入时确保持久化成功的复杂度,因为每个副本组上只有主副本会响应读写请求,备机一般配置只读来提供均衡读负载,选举这件事儿等价于让副本组内一个副本持有独占的写锁。 RocketMQ 为每个存储数据的 Broker 节点配置 ClusterName,BrokerName 标识来更好的进行资源管理。多个 BrokerName 相同的节点构成一个副本组。每个副本还拥有一个从 0 开始编号,不重复也不一定连续的 BrokerId 用来表示身份,编号为 0 的节点是这个副本组的 Leader / Primary / Master,故障时通过选举来重新对 Broker 编号标识新的身份。例如 BrokerId = {0, 1, 3},则 0 为主,其他两个为备。 一个副本组内,节点间共享数据的方式有多种,资源的共享程度由低到高来说一般有 Shared Nothing,Shared Disk,Shared Memory,Shared EveryThing。典型的 Shared Nothing 架构是 TiDB 这类纯分布式的数据库,TiDB 在每个存储节点上使用基于 RocksDB 封装的 TiKV 进行数据存储,上层通过协议交互实现事务或者 MVCC。相比于传统的分库分表策略来说,TiKV 易用性和灵活程度很高,更容易解决数据热点与伸缩时数据打散的一系列问题,但实现跨多节点的事务就需要涉及到多次网络的通信。另一端 Shared EveryThing 的案例是 AWS 的 Aurora,Aliyun 的 PolarStore,旁路 Kernal 的方式使应用完全运行于用户态,以最大程度的存储复用来减少资源消耗,一主多备完全共用一份底层可靠的存储,实现一写多读,快速切换。 大多数 KV 操作都是通过关键字的一致性哈希来计算所分配的节点,当这个节点所在的主副本组产生存储抖动,主备切换,网络分区等情况下,这个分片所对应的所有键都无法更新,局部会有一些操作失败。消息系统的模型有所不同,流量大但跨副本组的数据交互极少,无序消息发送到预期分区失败时还可以向其他副本组(分片)写入,一个副本组的故障不影响全局,这在整体服务的层面上额外提供了跨副本组的可用性。此外,考虑到 MQ 作为 Paas 层产品,被广泛部署于 Windows,Linux on Arm 等各种环境,只有减少和 Iaas 层产品的深度绑定,才能提供更好的灵活性。这种局部故障隔离和轻依赖的特性是 RocketMQ 选则 Shared Nothing 模型重要原因。 副本组中,各个节点处理的速度不同,也就有了日志水位的概念。Master 和与其差距不大的 Slave 共同组成了同步副本集(SyncStateSet)。如何定义差距不大呢?衡量的指标可以是日志水位(文件大小)差距较小,也可以是备落后的时间在一定范围内。在主宕机时,同步副本集中的其余节点有机会被提升为主,有时需要对系统进行容灾演练,或者对某些机器进行维护或灰度升级时希望定向的切换某一个副本成为新主,这又产生了优先副本(PriorityReplica)的概念。选择优先副本的原则和策略很多,可以动态选择水位最高,加入时间最久或 CommitLog 最长的副本,也可以支持机架,可用区优先这类静态策略。 从模型的角度来看,RocketMQ 单节点上 Topic 数量较多,如果像 kafka 以 topic / partition 粒度维护状态机,节点宕机会导致上万个状态机切换,这种惊群效应会带来很多潜在风险,因此 v4 版本时 RocketMQ 选择以单个 Broker 作为切换的最小粒度来管理,相比于其他更细粒度的实现,副本身份切换时只需要重分配 Broker 编号,对元数据节点压力最小。由于通信的数据量少,可以加快主备切换的速度,单个副本下线的影响被限制在副本组内,减少管理和运维成本。这种实现也一些缺点,例如存储节点的负载无法以最佳状态在集群上进行负载均衡,Topic 与存储节点本身的耦合度较高,水平扩展一般会改变分区总数,这就需要在上层附加额外的处理逻辑。 为了更规范更准确的衡量副本组的可用性指标,学术上就引入了几个名词: RTO(Recovery Time Objective)恢复时间目标,一般表示业务中断到恢复的时间。 RPO(Recovery Point Object)恢复点目标,用于衡量业务连续性。例如某个硬盘每天备份,故障时丢失最近备份后的所有更新。 SLA(ServiceLevel Agreement)服务等级协议,厂商以合约的形式对用户进行服务质量承诺,SLA 越高通常成本也越高。 节点数量与可靠性关系密切,根据不同生产场景,RocketMQ 的一个副本组可能会有 1,2,3,5 个副本。 1. 单副本成本最低,维护最简单,宕机时其他副本组接管新消息的写入,但已写入的数据无法读取,造成部分消息消费延迟。底层硬件故障还可能导致数据永久丢失,一般用于非关键日志,数据采集等低可靠性成本诉求较强的场景。 2. 两副本较好的权衡了数据冗余的成本与性能,RocketMQ 跨副本组容灾的特性使得两副本模式适用于绝大部分 IOPS 比较高的场景。此时备机可以分摊一定的读压力(尤其是主副本由于内存紧张或者产生冷读时)。两副本由于不满足多数派(quorum)原则,没有外部系统的参与时,故障时无法进行选举切换。 3. 三副本和五副本是业界使用最为广泛的,精心设计的算法使得多数情况下系统可以自愈。基于 Paxos / Raft 属于牺牲高可用性来保证一致性的 CP 型设计,存储成本很高,容易受到 IO 分布不均匀和水桶效应的影响。每条数据都需要半数以上副本响应的设计在需要写透(write through)多副本的消息场景下不够灵活。 日志复制还是消息复制 如何保证副本组中数据的最终一致性?那肯定是通过数据复制的方式实现,我们该选择逻辑复制还是物理复制呢? 逻辑复制:使用消息来进行同步的场景也很多,各种 connector 实现本质上就是把消息从一个系统挪到另外一个系统上,例如将数据导入导出到 ES,Flink 这样的系统上进行分析,根据业务需要选择特定 Topic / Tag 进行同步,灵活程度和可扩展性非常高。这种方案随着 Topic 增多,系统还会有服务发现,位点和心跳管理等上层实现造成的性能损失。因此对于消息同步的场景,RocketMQ 也支持以消息路由的形式进行数据转移,将消息复制作为业务消费的特例来看待。 物理复制:大名鼎鼎的 MySQL 对于操作会记录逻辑日志(bin log)和重做日志(redo log)两种日志。其中 bin log 记录了语句的原始逻辑,比如修改某一行某个字段,redo log 属于物理日志,记录了哪个表空间哪个数据页改了什么。在 RocketMQ 的场景下,存储层的 CommitLog 通过链表和内核的 MappedFile 机制抽象出一条 append only 的数据流。主副本将未提交的消息按序传输给其他副本(相当于 redo log),并根据一定规则计算确认位点(confirm offset)判断日志流是否被提交。这种方案仅使用一份日志和位点就可以保证主备之间预写日志的一致性,简化复制实现的同时也提高了性能。 为了可用性而设计的多副本结构,很明显是需要对所有需要持久化的数据进行复制的,选择物理复制更加节省资源。RocketMQ 在物理复制时又是如何保证数据的最终一致性呢?这就涉及到数据的水位对齐。对于消息和流这样近似 FIFO 的系统来说,越近期的消息价值越高,消息系统的副本组的单个节点不会像数据库系统一样,保留这个副本的全量数据,Broker 一方面不断的将冷数据规整并转入低频介质来节约成本,同时对热数据盘上的数据也会由远及近滚动删除。如果副本组中有副本宕机较久,或者在备份重建等场景下就会出现日志流的不对齐和分叉的复杂情况。在下图中我们将主节点的 CommitLog 的首尾位点作为参考点,这样就可以划分出三个区间。在下图中以蓝色箭头表示。排列组合一下就可以证明备机此时的 CommitLog 一定满足下列 6 种情况之一。 下面对每种情况进行讨论与分析: 11 情况下满足备 Max 主 Max,可能由于主异步写磁盘宕机后又成为主,或者网络分区时双主写入造成 CommitLog 分叉。由于新主落后于备,少量未确认的消息丢失,非正常模式的选举(RocketMQ 将这种情况称为 unclean 选举)是应该尽量避免的。 33 理论上不会出现,备的数据长于主,原因可能是主节点数据丢失又叠加了非正常选举,因此这种情况需要人工介入处理。 租约与节点身份变更 前文提到 RocketMQ 每个副本组的主副本才接受外部写请求,节点的身份又是如何决定的呢? 分布式系统一般分为中心化架构和去中心化架构。对于 MultiRaft,每个副本组包含三个或者五个副本,副本组内可以通过 Paxos / Raft 这样的共识协议来进行选主。典型的中心化架构,为了节省数据面资源成本会部署两副本,此时依赖于外部 ZK,ETCD,或者 DLedger Controller 这样的组件作为中心节点进行选举。由外置组件裁决成员身份涉及到分布式中两个重要的问题:1. 如何判断节点的状态是否正常。2. 如何避免双主问题。 对于第一个问题,kubernetes 的解决方案相对优雅,k8s 对与 Pod 的健康检查包括存活检测(Liveness probes)和就绪检测(Readiness probes),Liveness probes 主要是探测应用是否还活着,失败时重启 Pod。Readiness probes 来判断探测应用是否接受流量。简单的心跳机制一般只能实现存活检测,来看一个例子:假设有副本组中有 A、B、C 三个副本,另有一个节点 Q(哨兵) 负责观测节点状态,同时承担了全局选举与状态维护的职责。节点 A、B、C 周期性的向 Q 发送心跳,如果 Q 超过一段时间(一般是两个心跳间隔 )收不到某个节点的心跳则认为这个节点异常。如果异常的是主副本,Q 将副本组的其他副本提升为主并广播告知其他副本。 在工程实践中,节点下线的可能性一般要小于网络抖动的可能性。我们假设节点 A 是副本组的主,节点 Q 与节点 A 之间的网络中断。节点 Q 认为 A 异常。重新选择节点 B 作为新的 Master,并通知节点 A、B、C 新的 Master 是节点 B。节点 A 本身工作正常,与节点 B、C 之间的网络也正常。由于节点 Q 的通知事件到达节点 A、B、C 的顺序是未知的,假如先达到 B,在这一时刻,系统中同时存在两个工作的主,一个是 A,另一个是 B。假如此时 A、B 都接收外部请求并与 C 同步数据,会产生严重的数据错误。上述 "双主" 问题出现的原因在于虽然节点 Q 认为节点 A 异常,但节点 A 自己不认为自己异常,在旧主新主都接受写入的时候就产生了日志流的分叉,其问题的本质是由于网络分区造成的系统对于节点状态没有达成一致。 租约是一种避免双主的有效手段,租约的典型含义是现在中心节点承认哪个节点为主,并允许节点在租约有效期内正常工作。如果节点 Q 希望切换新的主,只需等待前一个主的租约过期,则就可以安全的颁发新租约给新 Master 节点,而不会出现双主问题。这种情况下系统对 Q 本身的可用性诉求非常高,可能会成为集群的性能瓶颈。生产中使用租约还有很多实现细节,例如依赖时钟同步需要颁发者的有效期设置的比接收者的略大,颁发者本身的切换也较为复杂。 在 RocketMQ 的设计中,希望以一种去中心化的设计降低中心节点宕机带来的全局风险,(这里认为中心化和是否存在中心节点是两件事)所以没有引入租约机制。在 Controller (对应于 Q )崩溃恢复期间,由于 Broker 对自己身份会进行永久缓存,每个主副本会管理这个副本组的状态机,RocketMQ Dledger Controller 这种模式能够尽量保证在大部分副本组在哨兵组件不可用时仍然不影响收发消息的核心流程。而旧主由于永久缓存身份,无法降级导致了网络分区时系统必须容忍双主。产生了多种解决方案,用户可以通过预配置选择 AP 型可用性优先,即允许系统通过短时分叉来保障服务连续性(下文还会继续谈谈为什么消息系统中分叉很难避免),还是 CP 型一致性优先,通过配置最小副本 ack 数超过集群半数以上节点。此时发送到旧主的消息将因为无法通过 ha 链路将数据发送给备,向客户端返回超时,由客户端将发起重试到其他分片。客户端经历一个服务发现的周期之后,客户端就可以正确发现新主。 特别的,在网络分区的情况下,例如旧主和备,Controller 之间产生网络分区,此时由于没有引入租约机制,旧主不会自动降级,旧主可以配置为异步双写,每一条消息需要经过主备的双重确认才能向客户端返回成功。而备在切换为主时,会设置自己只需要单个副本确认的同步写盘模式。此时,客户端短时间内仍然可以向旧主发送消息,旧主需要两副本确认才能返回成功,因此发送到旧主的消息会返回 SLAVE_NOT_AVAILABLE 的超时响应,通过客户端重试将消息发往新的节点。几秒后,客户端从 NameServer / Controller 获取新的路由时,旧主从客户端缓存中移除,此时完成了备节点的提升。 外置的组件可以对节点身份进行分配,上图展示了一个两副本的副本组上线流程: 1. 多个 Controller 通过选举和对 Broker 的请求进行重定向,最终由一个 Controller 做为主节点进行身份分配。 2. 如果 RocketMQ 副本组存在多个副本且需要选主,节点默认以备的身份启动,备节点会将自己注册到 Controller。 3. 节点从 Controller 获取 BrokerMemberGroup,包含了这个副本组的描述和连接信息。 1. 若分配的身份为备,解析出主节点的对外服务的地址并连接,完成日志截断后进行 HA 同步。 2. 若分配的身份为主,等待备机连接到自身的 HA 端口,并向 NameServer 再次宣告自己是主节点。 4. 主节点维护整个副本组的信息,向备发起数据复制,周期性的向 Controller 汇报主备之间水位差距,复制速度等。 RocketMQ 弱依赖 Controller 的实现并不会打破 Raft 中每个 term 最多只有一个 leader 的假设,工程中一般会使用 Leader Lease 解决脏读的问题,配合 Leader Stickiness 解决频繁切换的问题,保证主的唯一性。 Leader Lease: 租约,上一任 Leader 的 Lease 过期后,等待一段时间再发起 Leader 选举。 Leader Stickiness:Leader Lease 未过期的 Follower 拒绝新的 Leader 选举请求。 _注:Raft 认为具有最新已提交的日志的节点才有资格成为 Leader,而 MultiPaxos 无此限制。_ 对于日志的连续性问题,Raft 在确认一条日志之前会通过位点检查日志连续性,若检查到日志不连续会拒绝此日志,保证日志连续性,MultiPaxos 允许日志中有空洞。Raft 在 AppendEntries 中会携带 Leader 的 commit index,一旦日志形成多数派,Leader 更新本地的 commit index(对应于 RocketMQ 的 confirm offset)即完成提交,下一条 AppendEntries 会携带新的 commit index 通知其它节点,MultiPaxos 没有日志连接性假设,需要额外的 commit 消息通知其它节点。 计算日志分叉位点 除了网络分区,很多情况导致日志数据流分叉。有如下案例:三副本采用异步复制,异步持久化,A 为旧主 B C 为备,切换瞬间 B 日志水位大于 C,此时 C 成为新主,B C 副本上的数据会产生分叉,因为 B 还多出了一段未确认的数据。那么 B 是如何以一个简单可靠的方法去判断自己和 C 数据分叉的位点? 一个直观的想法就是,直接将主备的 CommitLog 从前向后逐渐字节比较,一般生产环境下,主备都有数百 GB 的日志文件流,读取和传输大量数据的方案费时费力。很快我们发现,确定两个大文件是否相同的一个好办法就是比较数据的哈希值,需要对比的数据量一下子就从数百 GB 降低为了几百个哈希值,对于第一个不相同的 CommitLog 文件,还可以采取局部哈希的方式对齐,这里仍然存在一些计算的代价。还有没有优化的空间呢,那就是利用任期 Epoch 和偏移量 StartOffset 实现一个新的截断算法。这种 EpochStartOffset 满足如下原则: 1. 通过共识协议保证给定的一个任期 Epoch 只有一个Leader。 2. 只有 Leader 可以写入新的数据流,满足一定条件才会被提交。 3. Follower 只能从 Leader 获取最新的数据流,Follower 上线时按照选举算法进行截断。 下面是一个选举截断的具体案例,选举截断算法思想和流程如下: 主 CommitLog Min = 300,Max = 2500,EpochMap = {, , }备 CommitLog Min = 300,Max = 2500,EpochMap = {, , } 1. 备节点连接到主节点进行 HA 协商,获取主节点的 EpochStartOffset 信息并比较 2. 备从后向前找到任期起始点相同的那个点作为分叉任期,在上述案例里是 3. 选择这个任期里主备结束位点的最小值(如果主副本没有切换且为最大任期,则主副本的结束位点是无穷大) 实现的代码如下: ${e} 数据回发与日志截断 故障发生后,系统将会对分叉数据进行修复,有很多小小细节值得深究与探讨。 在实现数据截断的过程中,有一个很特殊的动作,当备切主的时候要把 ConsumeQueue 的 Confirm Offset 提升到 CommitLog 的 MaxPhyOffset,即使这一部分数据在主上是否被提交是未知的。回想起几年前看 Raft 的时候,当一条日志被传输到 Follower,Follower 确认收到这条消息,主再把这条日志应用到自己的状态机时,通知客户端和通知所有的 follower 去 commit 这条日志这两件事是并行的,假如 leader 先回复 client 处理成功,此时 leader 挂了,由于其他 follower 的确认位点 confirm offset 一般会略低于 leader,中间这段未决日志还没应用到 follower 的状态机上,这时就出现了状态机不一致的情况,即已经写入 leader 的数据丢失了。让我们来举一个具体的案例,假设两副本一主一备: 1. 主的 max offset = 100,主向备发送当前 confirm offset = 40 和 message buffer = [40100] 的数据 2. 备向主回复 confirm offset = 100 后主需要同时做几件事 1. 本地提交(apply) [40100] 区间的数据,用后台的 dispatch 线程异步构建这段数据的索引 2. 向 producer 响应 [40100] 这段数据是发送成功的。 3. 向多个备机异步的提交,实际上是发送了 confirm offset = 100 3. 此时主突然宕机,备机的 confirm offset 可能是 [40100] 中的值 所以当备切换为主的时候,如果直接以 40 进行截断,意味着客户端已经发送到服务端的消息丢失了,正确的水位应该被提升至 100。但是备还没有收到 2.3 的 confirm = 100 的信息,这个行为相当于要提交了未决消息。事实上新 leader 会遵守 "Leader Completeness" 的约定,切换时任何副本都不会删除也不会更改旧 leader 未决的 entry。新 leader 在新的 term 下,会直接应用一个较大的版本将未决的 entry 一起提交,这里副本组主备节点的行为共同保证了复制状态机的安全性。 那么备切换成功的标志是什么,什么时候才能接收 producer 新的流量呢?对于 Raft 来说一旦切换就可以,对于 RocketMQ 来说这个阶段会被稍稍推迟,即索引已经完全构建结束的时候。RocketMQ 为了保证构建 consume queue 的一致性,会在 CommitLog 中记录 consume queue offset 的偏移量,此时 confirm offset 到 max offset 间的数据是副本作为备来接收的,这部分消息在 consume queue 中的偏移量已经固定下来了,而 producer 新的流量时由于 RocketMQ 预计算位点的优化,等到消息实际放入 CommitLog 的再真实的数据分发(dispatch)的时候就会发现对应位置的 consume queue 已经被占用了,此时就造成了主备索引数据不一致。本质原因是 RocketMQ 存储层预构建索引的优化对日志有一些侵入性,但切换时短暂等待的代价远远小于正常运行时提速的收益。 消息中间件场景 a. 元数据变更是否依赖于日志 目前 RocketMQ 对于元数据是在内存中单独管理的,备机间隔 5 秒向当前的主节点同步数据。例如当前主节点上创建了一个临时 Topic 并接受了一条消息,在一个同步周期内这个 Topic 又被删除了,此时主备节点元数据可能不一致。又比如位点更新的时候,对于单个队列而言,多副本架构中存在多条消费位点更新链路,Consumer 拉取消息时更新,Consumer 主动向 broker 更新,管控重置位点,HA 链路更新,当副本组发生主备切换时,consumer group 同时发生 consumer 上下线,由于路由发现的时间差,还可能造成同一个消费组两个不同 consumer 分别消费同一副本组主备上同一个队列的情况。 原因在于备机重做元数据更新和消息流这两件事是异步的,这有一定概率会造成脏数据。由于 RocketMQ 单个节点上 Topic / Group 数量较多,通过日志的实现会导致持久化的数据量很大,在复杂场景下基于日志做回滚依赖 snapshot 机制也会增加计算开销和恢复时间。这个问题和数据库很像,MySQL 在执行 DDL 修改元数据时通过会创建 MDL 锁,阻塞用户其他操作访问表空间的访问。备库同步主库也会加锁,元数据修改开始点和结束点所代表的两个日志并不是一个原子操作,这意味着主库上在修改元数据的过程中如果宕机了,备库上持有的 MDL 锁就无法释放。MySQL 的解决方案是在主库每次崩溃恢复后,都写一条特殊的日志,通知所有连接的备库释放其持有的所有 MDL 排他锁。对所有操作都走日志流进行状态机复制要求存储层有多种日志类型,实现也更加复杂。RocketMQ 选择以另一种同步的模式操作,即类似 ZAB 这样二阶段协议,例如位点更新时的可以选择配置 LockInStrictMode 让备都同步这条修改。事实上 RocketMQ 为了优化上述位点跳跃的现象,客户端在未重启时,遇到服务端主备切换还会用优先采纳本地位点的方式获取消息,进一步减少重复消费。 b. 同步复制与异步复制 同步复制的含义是用户的一个操作在多个副本上都已经提交。正常情况下,假设一个副本组中的 3 个副本都要对相同一个请求进行确认,相当于数据写透 3 个副本(简称 33 写),33 写提供了非常高的数据可靠性,但是把所有从节点都配置为同步复制时任何一个同步节点的中断都会导致整个副本组处理请求失败。当第三个副本是跨可用区时,长尾也会带来一定的延迟。 异步复制模式下,尚未复制到从节点的写请求都会丢失。向客户端确认的写操作也无法保证被持久化。异步复制是一种故障时 RPO 不为 0 的配置模式,由于不用考虑从节点上的状态,总是可以继续响应写请求,系统的延迟更低,吞吐性能更好。为了权衡两者,通常只有其中一个从节点是同步的,而其他节点是异步的模式。只要同步的从节点变得不可用或性能下降,则将另一个异步的从节点提升为同步模式。这样可以保证至少有两个节点(即主节点和一个同步从节点)拥有最新的数据副本。这种模式称为 23 写,能帮助避免抖动,提供更好的延迟稳定性,有时候也叫称为半同步。 在 RocketMQ 的场景中,异步复制也被广泛应用在消息读写比极高,从节点数量多或者异地多副本场景。同步复制和异步复制是通过 Broker 配置文件里的 brokerRole 参数进行设置的,这个参数可以被设置成 ASYNC_MASTER、SYNC_MASTER、SLAVE 三个值中的一个。实际应用中要结合业务场景合理设置持久化方式和主从复制方式,通常,由于网络的速度高于本地 IO 速度,采用异步持久化和同步复制是一个权衡性能与可靠性的设置。 c. 副本组自适应降级 同步复制的含义是一条数据同时被主备确认才返回用户操作成功,可以保证主宕机后消息还在备中,适合可靠性要求较高的场景,同步复制还可以限制未同步的数据量以减少 ha 链路的内存压力,缺点则是副本组中的某一个备出现假死就会影响写入。异步复制无需等待备确认,性能高于同步复制,切换时未提交的消息可能会丢失(参考前文的日志分叉)。在三副本甚至五副本且对可靠性要求高的场景中无法采用异步复制,采用同步复制需要每一个副本确认后才会返回,在副本数多的情况下严重影响效率。关于一条消息需要被多少副本确认这个问题,RocketMQ 服务端会有一些数量上的配置来进行灵活调整: TotalReplicas:全部副本数 InSyncReplicas:每条消息至少要被这个数量的 Broker 确认(如果主为 ASYNC_MASTER 或者 AllAck 模式则该参数不生效) MinInSyncReplicas:最小的同步副本数,如果 InSyncReplicas 。对于正常情况下,两个副本会处于同步复制,当备下线或假死时,会进行自适应降级,保证主节点还能正常收发消息,这个功能为用户提供了一个可用性优先的选择。 d. 轻量级心跳与快速隔离 在 RocketMQ v4.x 版本的实现中,Broker 周期性的(间隔 30 秒)将自身的所有 Topic 序列化并传输到 NameServer 注册进行保活。由于 Broker 上 Topic 的元数据规模较大,带来了较大的网络流量开销,Broker 的注册间隔不能设置的太短。同时 NameServer 对 Broker 是采取延迟隔离机制,防止 NameServer 网络抖动时可能瞬间移除所有 Broker 的注册信息,引发服务的雪崩。默认情况下异常主宕机时超过 2 分钟,或者备切换为主重新注册后才会替换。容错设计的同时导致 Broker 故障转移缓慢,RocketMQ v5.0 版本引入轻量级心跳(参数liteHeartBeat),将 Broker 的注册行为与 NameServer 的心跳进行了逻辑拆分,将心跳间隔减小到 1 秒。当 NameServer 间隔 5 秒(可配置)没有收到来自 Broker 的心跳请求就对 Broker 进行移除,使异常场景下自愈的时间从分钟级缩短到了秒级。 RocketMQ 高可用架构演进路线 无切换架构的演进 最早的时候,RocketMQ 基于 MasterSlave 模式提供了主备部署的架构,这种模式提供了一定的高可用能力,在 Master 节点负载较高情况下,读流量可以被重定向到备机。由于没有选主机制,在 Master 节点不可用时,这个副本组的消息发送将会完全中断,还会出现延迟消息、事务消息、Pop 消息等二级消息无法消费或者延迟。此外,备机在正常工作场景下资源使用率较低,造成一定的资源浪费。为了解决这些问题,社区提出了在一个 Broker 进程内运行多个 BrokerContainer,这个设计类似于 Flink 的 slot,让一个 Broker 进程上可以以 Container 的形式运行多个节点,复用传输层的连接,业务线程池等资源,通过单节点主备交叉部署来同时承担多份流量,无外部依赖,自愈能力强。这种方式下隔离性弱于使用原生容器方式进行隔离,同时由于架构的复杂度增加导致了自愈流程较为复杂。 切换架构的演进 另一条演进路线则是基于可切换的,RocketMQ 也尝试过依托于 Zookeeper 的分布式锁和通知机制进行 HA 状态的管理。引入外部依赖的同时给架构带来了复杂性,不容易做小型化部署,部署运维和诊断的成本较高。另一种方式就是基于 Raft 在集群内自动选主,Raft 中的副本身份被透出和复用到 Broker Role 层面去除外部依赖,然而强一致的 Raft 版本并未支持灵活的降级策略,无法在 C 和 A 之间灵活调整。两种切换方案都是 CP 设计,牺牲高可用优先保证一致性。主副本下线时选主和路由定时更新策略导致整个故障转移时间依然较长,Raft 本身对三副本的要求也会面临较大的成本压力,RocketMQ 原生的 TransientPool,零拷贝等一些用来避免减少 IO 压力的方案在 Raft 下无法有效使用。 RocketMQ DLedger 融合模式 RocketMQ DLedger 融合模式是 RocketMQ 5.0 演进中结合上述两条路线后的一个系统的解决方案。核心的特性有以下几点: 1. 利用可内嵌于 NameServer 的 Controller 进行选主,无外部依赖,对两副本支持友好。 2. 引入 EpochStartOffset 机制来计算日志分叉位点。 3. 消息在进行写入时,提供了灵活的配置来协调系统对于可用性还是一致性优先的诉求。 4. 简化日志复制协议使得日志复制为高效。 几种实现对比表如下: 与其他消息系统的对比 控制节点 1. 是否强制要求选主 Kafka 的 Controller 是 Broker 选举产生,这需要有一个存储节点间的服务发现机制。RocketMQ 的 Controller 可以作为管控节点单独存在。对 Kafka,Pulsar 而言必须选择主副本进行写入,随着时间的运行节点之间负载需要通过复杂的方案进行再均衡。对 RocketMQ 的融合架构而言,由于选主是可选的,静态布局的方案(例如无需依赖复杂的动态调度就可以较为均衡的实现跨机架跨可用区),并且无切换与切换架构可以相互转换。 2. Controller 的逻辑复杂度 RocketMQ Controller 相比 Kafka Controller 更加轻量,Kafka 的 Controller 承担 Partition 粒度的 ISR 维护和选举等功能,而RocketMQ 的 Controller 维护的数据是副本组粒度的,对于元数据只维护节点身份,更加简单。RocketMQ Controller 可以独立部署,也可以内嵌 NameServer 运行。 3. Controller 依赖程度 RocketMQ Broker 的同步副本集维护是 Master Broker 节点上报,由于不强依赖中心节点来提供租约,controller 宕机时虽然无法为同时有主故障的副本组选举,但不影响绝大部分副本组可用性。Pulsar 中通过 fencing 机制防止有多个 writer(pulsar 中的计算节点称为 broker)同时写同一个 partition,是对外部有依赖的。 数据节点 1. 副本存储结构的抽象与最小粒度不同,在这一点上其实三者的设计各有优势 Kafka 的存储抽象粒度是 Partition,对每个分区进行维护多副本,扩容需要进行数据复制,对于冷读支持更好。 RocketMQ 的日志流是 Broker 粒度的,顺序写盘效率更高,在磁盘空间不足时一般选择水平扩容,只需复制元数据。 Pulsar 其实抽象了一个分布式日志流 Journal,分区被进一步分成分片,根据配置的时间或大小进行滚动,扩容只需复制元数据。 2. 复杂的参数配置被收敛至服务端 Kafka 和 RocketMQ 都支持灵活的配置单条消息的 ack 数,即权衡数据写入灵活性与可靠性。RocketMQ 在向云原生演进的过程希望简化客户端 API 与配置,让业务方只需关心消息本身,选择在服务端配置统一配置这个值。 3. 副本数据的同步方式不同 Pulsar 采用星型写:数据直接从 writer 写到多个 bookeeper。适合客户端与存储节点混部场景。数据路径只需要 1 跳,延迟更低。缺点是当存储计算分离时,星型写需要更多的存储集群和计算集群间网络带宽。 RocketMQ 和 Kafka 采用 Y 型写:client 先写到一个主副本,由其再转发给另外 Broker 副本。虽然服务端内部带宽充裕,但需要 2 跳网络,会增加延迟。Y 型写利于解决文件多客户端写的问题,也更容易利用 23 写克服毛刺,提供更好的延迟稳定性。 高可用架构的未来 仔细阅读 RocketMQ 的源码,其实大家也会发现 RocketMQ 在各种边缘问题处理上细节满满,节点失效,网络抖动,副本一致性,持久化,可用性与延迟之间存在各种细微的权衡,这也是 RocketMQ 多年来在生产环境下所积累的核心竞争力之一。随着分布式技术的进一步发展,更多更有意思的技术,如基于 RDMA 网络的复制协议也呼之欲出。RocketMQ 将与社区协同进步,发展为 “消息,事件,流” 一体化的融合平台。 参考文档: 1. Paxos design: 2. SOFAJRaft: 3. Pulsar Geo Replication: 4. Pulsar Metadata: 5. Kafka Persistence: 6. Kafka Balancing leadership: 7. Windows Azure Storage: A Highly Available Cloud Storage Service with Strong Consistency: 8. PolarDB Serverless: A Cloud Native Database for Disaggregated Data Centers: 活动推荐 阿里云基于 Apache RocketMQ 构建的企业级产品消息队列RocketMQ 5.0版现开启活动: 1、新用户首次购买包年包月,即可享受全系列 85折优惠! 了解活动详情:
作者:斜阳
#技术探索 #强力推荐 #高可用

2021年4月22日

使用 rocketmq-spring-boot-starter 来配置、发送和消费 RocketMQ 消息
导读:本文将 rocktmqspringboot 的设计实现做一个简单的介绍,读者可以通过本文了解将 RocketMQ Client 端集成为 springbootstarter 框架的开发细节,然后通过一个简单的示例来一步一步的讲解如何使用这个 springbootstarter 工具包来配置,发送和消费 RocketMQ 消息。 在 Spring 生态中玩转 RocketMQ 系列文章: 本文配套可交互教程已登录阿里云知行动手实验室,PC 端登录 在浏览器中立即体验。 通过本文,您将了解到: Spring 的消息框架介绍 rocketmqspringboot 具体实现 使用示例 前言 上世纪 90 年代末,随着 Java EE(Enterprise Edition) 的出现,特别是 Enterprise Java Beans 的使用需要复杂的描述符配置和死板复杂的代码实现,增加了广大开发者的学习曲线和开发成本,由此基于简单的 XML 配置和普通 Java 对象(Plain Old Java Objects)的 Spring 技术应运而生,依赖注入(Dependency Injection), 控制反转(Inversion of Control)和面向切面编程(AOP)的技术更加敏捷地解决了传统 Java 企业及版本的不足。 随着 Spring 的持续演进,基于注解(Annotation)的配置逐渐取代了 XML 文件配置,2014 年 4 月 1 日,Spring Boot 1.0.0 正式发布,它基于“约定大于配置”(Convention over configuration)这一理念来快速地开发、测试、运行和部署 Spring 应用,并能通过简单地与各种启动器(如 springbootwebstarter)结合,让应用直接以命令行的方式运行,不需再部署到独立容器中。这种简便直接快速构建和开发应用的过程,可以使用约定的配置并且简化部署,受到越来越多的开发者的欢迎。 Apache RocketMQ 是业界知名的分布式消息和流处理中间件,简单地理解,它由 Broker 服务器和客户端两部分组成: 其中客户端一个是消息发布者客户端(Producer),它负责向 Broker 服务器发送消息;另外一个是消息的消费者客户端(Consumer),多个消费者可以组成一个消费组,来订阅和拉取消费 Broker 服务器上存储的消息。 为了利用 Spring Boot 的快速开发和让用户能够更灵活地使用 RocketMQ 消息客户端,Apache RocketMQ 社区推出了 springbootstarter 实现。随着分布式事务消息功能在 RocketMQ 4.3.0 版本的发布,近期升级了相关的 springboot 代码,通过注解方式支持分布式事务的回查和事务消息的发送。 本文将对当前的设计实现做一个简单的介绍,读者可以通过本文了解将 RocketMQ Client 端集成为 springbootstarter 框架的开发细节,然后通过一个简单的示例来一步一步的讲解如何使用这个 springbootstarter 工具包来配置,发送和消费 RocketMQ 消息。 Spring 中的消息框架 顺便在这里讨论一下在 Spring 中关于消息的两个主要的框架,即 Spring Messaging 和 Spring Cloud Stream。它们都能够与 Spring Boot 整合并提供了一些参考的实现。和所有的实现框架一样,消息框架的目的是实现轻量级的消息驱动的微服务,可以有效地简化开发人员对消息中间件的使用复杂度,让系统开发人员可以有更多的精力关注于核心业务逻辑的处理。 1. Spring Messaging Spring Messaging 是 Spring Framework 4 中添加的模块,是 Spring 与消息系统集成的一个扩展性的支持。它实现了从基于 JmsTemplate 的简单的使用 JMS 接口到异步接收消息的一整套完整的基础架构,Spring AMQP 提供了该协议所要求的类似的功能集。在与 Spring Boot 的集成后,它拥有了自动配置能力,能够在测试和运行时与相应的消息传递系统进行集成。 单纯对于客户端而言,Spring Messaging 提供了一套抽象的 API 或者说是约定的标准,对消息发送端和消息接收端的模式进行规定,不同的消息中间件提供商可以在这个模式下提供自己的 Spring 实现:在消息发送端需要实现的是一个 XXXTemplate 形式的 Java Bean,结合 Spring Boot 的自动化配置选项提供多个不同的发送消息方法;在消息的消费端是一个 XXXMessageListener 接口(实现方式通常会使用一个注解来声明一个消息驱动的 POJO),提供回调方法来监听和消费消息,这个接口同样可以使用 Spring Boot 的自动化选项和一些定制化的属性。 如果有兴趣深入的了解 Spring Messaging 及针对不同的消息产品的使用,推荐阅读这个文件。参考 Spring Messaging 的既有实现,RocketMQ 的 springbootstarter 中遵循了相关的设计模式并结合 RocketMQ 自身的功能特点提供了相应的 API(如顺序、异步和事务半消息等)。 2. Spring Cloud Stream Spring Cloud Stream 结合了 Spring Integration 的注解和功能,它的应用模型如下: 该图片引自 spring cloud stream Spring Cloud Stream 框架中提供一个独立的应用内核,它通过输入(@Input)和输出(@Output)通道与外部世界进行通信,消息源端(Source)通过输入通道发送消息,消费目标端(Sink)通过监听输出通道来获取消费的消息。这些通道通过专用的 Binder 实现与外部代理连接。开发人员的代码只需要针对应用内核提供的固定的接口和注解方式进行编程,而不需要关心运行时具体的 Binder 绑定的消息中间件。在运行时,Spring Cloud Stream 能够自动探测并使用在 classpath 下找到的Binder。 这样开发人员可以轻松地在相同的代码中使用不同类型的中间件:仅仅需要在构建时包含进不同的 Binder。在更加复杂的使用场景中,也可以在应用中打包多个 Binder 并让它自己选择 Binder,甚至在运行时为不同的通道使用不同的 Binder。 Binder 抽象使得 Spring Cloud Stream 应用可以灵活的连接到中间件,加之 Spring Cloud Stream 使用利用了 Spring Boot 的灵活配置配置能力,这样的配置可以通过外部配置的属性和 Spring Boot 支持的任何形式来提供(包括应用启动参数、环境变量和 application.yml 或者 application.properties 文件),部署人员可以在运行时动态选择通道连接 destination(例如,Kafka 的 topic 或者 RabbitMQ 的 exchange)。 Binder SPI 的方式来让消息中间件产品使用可扩展的 API 来编写相应的 Binder,并集成到 Spring Cloud Steam 环境,目前 RocketMQ 还没有提供相关的 Binder,我们计划在下一步将完善这一功能,也希望社区里有这方面经验的同学积极尝试,贡献 PR 或建议。 springbootstarter的实现 在开始的时候我们已经知道,spring boot starter 构造的启动器对于使用者是非常方便的,使用者只要在 pom.xml引入starter 的依赖定义,相应的编译,运行和部署功能就全部自动引入。因此常用的开源组件都会为 Spring 的用户提供一个 springbootstarter 封装给开发者,让开发者非常方便集成和使用,这里我们详细的介绍一下 RocketMQ(客户端)的 starter 实现过程。 1. springbootstarter 的实现步骤 对于一个 springbootstarter 实现需要包含如下几个部分: 1)在 pom.xml 的定义 定义最终要生成的 starter 组件信息 org.apache.rocketmq springbootstarterrocketmq 1.0.0SNAPSHOT 定义依赖包 它分为两个部分:Spring 自身的依赖包和 RocketMQ 的依赖包。 2)配置文件类 定义应用属性配置文件类 RocketMQProperties,这个 Bean 定义一组默认的属性值。用户在使用最终的 starter 时,可以根据这个类定义的属性来修改取值,当然不是直接修改这个类的配置,而是 springboot 应用中对应的配置文件:src/main/resources/application.properties。 3)定义自动加载类 定义 src/resources/METAINF/spring.factories 文件中的自动加载类, 其目的是让 spring boot 更具文中中所指定的自动化配置类来自动初始化相关的 Bean、Component 或 Service,它的内容如下: org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.apache.rocketmq.spring.starter.RocketMQAutoConfiguration 在 RocketMQAutoConfiguration 类的具体实现中,定义开放给用户直接使用的 Bean 对象包括: RocketMQProperties 加载应用属性配置文件的处理类; RocketMQTemplate 发送端用户发送消息的发送模板类; ListenerContainerConfiguration 容器 Bean 负责发现和注册消费端消费实现接口类,这个类要求:由 @RocketMQMessageListener 注解标注;实现 RocketMQListener 泛化接口。 4)最后具体地进行 RpcketMQ 相关的封装 在发送端(producer)和消费端(consumer)客户端分别进行封装,在当前的实现版本提供了对 Spring Messaging 接口的兼容方式。 2. 消息发送端实现 1)普通发送端 发送端的代码封装在 RocketMQTemplate POJO 中,下图是发送端的相关代码的调用关系图: 为了与 Spring Messaging 的发送模板兼容,在 RocketMQTemplate 集成了 AbstractMessageSendingTemplate 抽象类,来支持相关的消息转换和发送方法,这些方法最终会代理给 doSend() 方法、doSend() 以及 RocoketMQ 所特有的一些方法如异步,单向和顺序等方法直接添加到 RoketMQTempalte 中,这些方法直接代理调用到 RocketMQ 的 Producer API 来进行消息的发送。 2)事务消息发送端 对于事务消息的处理,在消息发送端进行了部分的扩展,参考上面的调用关系类图。 RocketMQTemplate 里加入了一个发送事务消息的方法 sendMessageInTransaction(),并且最终这个方法会代理到 RocketMQ 的 TransactionProducer 进行调用,在这个 Producer 上会注册其关联的 TransactionListener 实现类,以便在发送消息后能够对 TransactionListener 里的方法实现进行调用。 3. 消息消费端实现 在消费端 SpringBoot 应用启动后,会扫描所有包含 @RocketMQMessageListener 注解的类(这些类需要集成 RocketMQListener 接口,并实现 onMessage()方法),这个 Listener 会一对一的被放置到。 DefaultRocketMQListenerContainer 容器对象中,容器对象会根据消费的方式(并发或顺序),将 RocketMQListener 封装到具体的 RocketMQ 内部的并发或者顺序接口实现。在容器中创建 RocketMQ Consumer 对象,启动并监听定制的 Topic 消息,如果有消费消息,则回调到 Listener 的 onMessage() 方法。 使用示例 上面的一章介绍了 RocketMQ 在 springbootstarter 方式的实现,这里通过一个最简单的消息发送和消费的例子来介绍如何使这个 rocketmqspringbootstarter。 1. RocketMQ 服务端的准备 1)启动 NameServer 和 Broker 要验证 RocketMQ 的 SpringBoot 客户端,首先要确保 RocketMQ 服务正确的下载并启动。可以参考 RocketMQ 主站的快速开始来进行操作。确保启动 NameServer 和 Broker 已经正确启动。 2)创建实例中所需要的 Topics 在执行启动命令的目录下执行下面的命令行操作: bash bin/mqadmin updateTopic c DefaultCluster t stringtopic 2. 编译 rocketmqspringbootstarter 目前的 springbootstarter 依赖还没有提交的 Maven 的中心库,用户使用前需要自行下载 git 源码,然后执行 mvn clean install 安装到本地仓库。 git clone https://github.com/apache/rocketmqexternals.git cd rocketmqspringbootstarter mvn clean install 3. 编写客户端代码 用户如果使用它,需要在消息的发布和消费客户端的 maven 配置文件 pom.xml 中添加如下的依赖: 属性 springbootstarterrocketmqversion 的取值为:1.0.0SNAPSHOT, 这与上一步骤中执行安装到本地仓库的版本一致。 1)消息发送端的代码 发送端的配置文件 application.properties: 发送端的 Java 代码: 2)消息消费端代码 消费端的配置文件 application.properties: 消费端的 Java 代码: 这里只是简单的介绍了使用 springboot 来编写最基本的消息发送和接收的代码,如果需要了解更多的调用方式,如: 异步发送,对象消息体,指定 tag 标签以及指定事务消息,请参看 github 的说明文档和详细的代码。我们后续还会对这些高级功能进行陆续的介绍。 作者简介 辽天,阿里巴巴技术专家,Apache RocketMQ 内核控,拥有多年分布式系统研发经验,对 Microservice、Messaging 和 Storage 等领域有深刻理解, 目前专注 RocketMQ 内核优化以及 Messaging 生态建设。 在 PC 端登录 start.aliyun.com 知行动手实验室,沉浸式体验在线交互教程。 活动推荐 阿里云基于 Apache RocketMQ 构建的企业级产品消息队列RocketMQ 5.0版现开启活动: 1、新用户首次购买包年包月,即可享受全系列 85折优惠! 了解活动详情:
作者:辽天
#技术探索 #微服务

2021年4月6日

基于 RocketMQ Prometheus Exporter 打造定制化 DevOps 平台
导读:本文将对 RocketMQExporter 的设计实现做一个简单的介绍,读者可通过本文了解到 RocketMQExporter 的实现过程,以及通过 RocketMQExporter 来搭建自己的 RocketMQ 监控系统。RocketMQ 在线可交互教程现已登录知行动手实验室,PC 端登录 start.aliyun.com 即可直达。 RocketMQ 云原生系列文章: (本文) RocketMQExporter 项目的 GitHub 地址: 文章主要内容包含以下几个方面: 1. RocketMQ 介绍 2. Prometheus 简介 3. RocketMQExporter 的具体实现 4. RocketMQExporter 的监控指标和告警指标 5. RocketMQExporter 使用示例 RocketMQ 介绍 RocketMQ 是一个分布式消息和流数据平台,具有低延迟、高性能、高可靠性、万亿级容量和灵活的可扩展性。简单的来说,它由 Broker 服务器和客户端两部分组成,其中客户端一个是消息发布者客户端(Producer),它负责向 Broker 服务器发送消息;另外一个是消息的消费者客户端(Consumer),多个消费者可以组成一个消费组,来订阅和拉取消费 Broker 服务器上存储的消息。 正由于它具有高性能、高可靠性和高实时性的特点,与其他协议组件在 MQTT 等各种消息场景中的结合也越来越多,应用越来越广泛。而对于这样一个强大的消息中间件平台,在实际使用的时候还缺少一个监控管理平台。 当前在开源界,使用最广泛监控解决方案的就是 Prometheus。与其它传统监控系统相比较,Prometheus 具有易于管理,监控服务的内部运行状态,强大的数据模型,强大的查询语言 PromQL,高效的数据处理,可扩展,易于集成,可视化,开放性等优点。并且借助于 Prometheus 可以很快速的构建出一个能够监控 RocketMQ 的监控平台。 Prometheus 简介 下图展示了 Prometheus 的基本架构: 1. Prometheus Server Prometheus Server 是 Prometheus 组件中的核心部分,负责实现对监控数据的获取,存储以及查询。Prometheus Server 可以通过静态配置管理监控目标,也可以配合使用 Service Discovery 的方式动态管理监控目标,并从这些监控目标中获取数据。其次 Prometheus Server 需要对采集到的监控数据进行存储,Prometheus Server 本身就是一个时序数据库,将采集到的监控数据按照时间序列的方式存储在本地磁盘当中。最后 Prometheus Server 对外提供了自定义的 PromQL 语言,实现对数据的查询以及分析。 2. Exporters Exporter 将监控数据采集的端点通过 HTTP 服务的形式暴露给 Prometheus Server,Prometheus Server 通过访问该 Exporter 提供的 Endpoint 端点,即可获取到需要采集的监控数据。RocketMQExporter 就是这样一个 Exporter,它首先从 RocketMQ 集群采集数据,然后借助 Prometheus 提供的第三方客户端库将采集的数据规范化成符合 Prometheus 系统要求的数据,Prometheus 定时去从 Exporter 拉取数据即可。 当前 RocketMQ Exporter 已被 Prometheus 官方收录,其地址为:。 RocketMQExporter 的具体实现 当前在 Exporter 当中,实现原理如下图所示: 整个系统基于 spring boot 框架来实现。由于 MQ 内部本身提供了比较全面的数据统计信息,所以对于 Exporter 而言,只需要将 MQ 集群提供的统计信息取出然后进行加工而已。所以 RocketMQExporter 的基本逻辑是内部启动多个定时任务周期性的从 MQ 集群拉取数据,然后将数据规范化后通过端点暴露给 Prometheus 即可。其中主要包含如下主要的三个功能部分: MQAdminExt 模块通过封装 MQ 系统客户端提供的接口来获取 MQ 集群内部的统计信息。 MetricService 负责将 MQ 集群返回的结果数据进行加工,使其符合 Prometheus 要求的格式化数据。 Collect 模块负责存储规范化后的数据,最后当 Prometheus 定时从 Exporter 拉取数据的时候,Exporter 就将 Collector 收集的数据通过 HTTP 的形式在/metrics 端点进行暴露。 RocketMQExporter 的监控指标和告警指标 RocketMQExporter 主要是配合 Prometheus 来做监控,下面来看看当前在 Expoter 中定义了哪些监控指标和告警指标。 监控指标 rocketmq_message_accumulation 是一个聚合指标,需要根据其它上报指标聚合生成。 告警指标 消费者堆积告警指标也是一个聚合指标,它根据消费堆积的聚合指标生成,value 这个阈值对每个消费者是不固定的,当前是根据过去 5 分钟生产者生产的消息数量来定,用户也可以根据实际情况自行设定该阈值。告警指标设置的值只是个阈值只是象征性的值,用户可根据在实际使用 RocketMQ 的情况下自行设定。这里重点介绍一下消费者堆积告警指标,在以往的监控系统中,由于没有像 Prometheus 那样有强大的 PromQL 语言,在处理消费者告警问题时势必需要为每个消费者设置告警,那这样就需要 RocketMQ 系统的维护人员为每个消费者添加,要么在系统后台检测到有新的消费者创建时自动添加。在 Prometheus 中,这可以通过一条如下的语句来实现: (sum(rocketmq_producer_offset) by (topic) on(topic) group_right sum(rocketmq_consumer_offset) by (group,topic)) ignoring(group) group_left sum (avg_over_time(rocketmq_producer_tps[5m])) by (topic)560 0 借助 PromQL 这一条语句不仅可以实现为任意一个消费者创建消费告警堆积告警,而且还可以使消费堆积的阈值取一个跟生产者发送速度相关的阈值。这样大大增加了消费堆积告警的准确性。 RocketMQExporter 使用示例 1. 启动 NameServer 和 Broker 要验证 RocketMQ 的 SpringBoot 客户端,首先要确保 RocketMQ 服务正确的下载并启动。可以参考 RocketMQ 主站的快速开始来进行操作。确保启动 NameServer 和 Broker 已经正确启动。 2. 编译 RocketMQExporter 用户当前使用,需要自行下载 git 源码编译: git clone https://github.com/apache/rocketmqexporter cd rocketmqexporter mvn clean install 3. 配置和运行 RocketMQExporter 有如下的运行选项: 以上的运行选项既可以在下载代码后在配置文件中更改,也可以通过命令行来设置。 编译出来的 jar 包就叫 rocketmqexporter0.0.1SNAPSHOT.jar,可以通过如下的方式来运行。 java jar rocketmqexporter0.0.1SNAPSHOT.jar [rocketmq.config.namesrvAddr="127.0.0.1:9876" ...] 4. 安装 Prometheus 首先到 Prometheus去下载 Prometheus 安装包,当前以 linux 系统安装为例,选择的安装包为 prometheus2.7.0rc.1.linuxamd64.tar.gz,经过如下的操作步骤就可以启动 prometheus 进程。 tar xzf prometheus2.7.0rc.1.linuxamd64.tar.gzcd prometheus2.7.0rc.1.linuxamd64/./prometheus config.file=prometheus.yml web.listenaddress=:5555 Prometheus 默认监听端口号为 9090,为了不与系统上的其它进程监听端口冲突,我们在启动参数里面重新设置了监听端口号为 5555。然后通过浏览器访问 ;服务器 IP 地址:5555,就可以验证 Prometheus 是否已成功安装,显示界面如下: 由于 RocketMQExporter 进程已启动,这个时候可以通过 Prometheus 来抓取 RocketMQExporter 的数据,这个时候只需要更改 Prometheus 启动的配置文件即可。 整体配置文件如下: my global config global: scrape_interval: 15s Set the scrape interval to every 15 seconds. Default is every 1 minute. evaluation_interval: 15s Evaluate rules every 15 seconds. The default is every 1 minute. scrape_timeout is set to the global default (10s). Load rules once and periodically evaluate them according to the global 'evaluation_interval'. rule_files: "first_rules.yml" "second_rules.yml" scrape_configs: job_name: 'prometheus' static_configs: targets: ['localhost:5555'] job_name: 'exporter' static_configs: targets: ['localhost:5557'] 更改配置文件后,重启服务即可。重启后就可以在 Prometheus 界面查询 RocketMQExporter 上报的指标,例如查询 rocketmq_broker_tps 指标,其结果如下: 5. 告警规则添加 在 Prometheus 可以展示 RocketMQExporter 的指标后,就可以在 Prometheus 中配置 RocketMQ 的告警指标了。在 Prometheus 的配置文件中添加如下的告警配置项,.rules 表示可以匹配多个后缀为 rules 的文件。 rule_files: "first_rules.yml" "second_rules.yml" /home/prometheus/prometheus2.7.0rc.1.linuxamd64/rules/.rules 当前设置的告警配置文件为 warn.rules,其文件具体内容如下所示。其中的阈值只起一个示例的作用,具体的阈值还需用户根据实际使用情况来自行设定。 Sample prometheus rules/alerts for rocketmq. Galera Alerts groups: name: GaleraAlerts rules: alert: RocketMQClusterProduceHigh expr: sum(rocketmq_producer_tps) by (cluster) = 10 for: 3m labels: severity: warning annotations: description: '{{$labels.cluster}} Sending tps too high.' summary: cluster send tps too high alert: RocketMQClusterProduceLow expr: sum(rocketmq_producer_tps) by (cluster) = 10 for: 3m labels: severity: warning annotations: description: '{{$labels.cluster}} consuming tps too high.' summary: cluster consume tps too high alert: RocketMQClusterConsumeLow expr: sum(rocketmq_consumer_tps) by (cluster) 0 for: 3m labels: severity: warning annotations: description: 'consumer {{$labels.group}} on {{$labels.topic}} lag behind and is falling behind (behind value {{$value}}).' summary: consumer lag behind alert: GroupGetLatencyByStoretime expr: rocketmq_group_get_latency_by_storetime 1000 for: 3m labels: severity: warning annotations: description: 'consumer {{$labels.group}} on {{$labels.broker}}, {{$labels.topic}} consume time lag behind message store time and (behind value is {{$value}}).' summary: message consumes time lag behind message store time too much 最终,可以在 Prometheus 的看一下告警展示效果,红色表示当前处于告警状态的项,绿色表示正常状态。 6. Grafana dashboard for RocketMQ Prometheus 自身的指标展示平台没有当前流行的展示平台 Grafana 好, 为了更好的展示 RocketMQ 的指标,可以使用 Grafana 来展示 Prometheus 获取的指标。 首先到官网去下载:,这里仍以二进制文件安装为例进行介绍。 wget https://dl.grafana.com/oss/release/grafana6.2.5.linuxamd64.tar.gz tar zxvf grafana6.2.5.linuxamd64.tar.gz cd grafana5.4.3/ 同样为了不与其它进程的使用端口冲突,可以修改 conf 目录下的 defaults.ini 文件的监听端口,当前将 grafana 的监听端口改为 55555,然后使用如下的命令启动即可: ./bin/grafanaserver web 然后通过浏览器访问 ;服务器 IP 地址:55555,就可以验证 grafana 是否已成功安装。系统默认用户名和密码为 admin/admin,第一次登陆系统会要求修改密码,修改密码后登陆,界面显示如下: 点击 Add data source 按钮,会要求选择数据源。 选择数据源为 Prometheus,设置数据源的地址为前面步骤启动的 Prometheus 的地址。 回到主界面会要求创建新的 Dashboard。 点击创建 dashboard,创建 dashboard 可以自己手动创建,也可以以配置文件导入的方式创建,当前已将 RocketMQ 的 dashboard 配置文件上传到 Grafana 的官网,这里以配置文件导入的方式进行创建。 点击 New dashboard 下拉按钮。 选择 import dashboard。 这个时候可以到 Grafana 官网去下载当前已为 RocketMQ 创建好的配置文件,地址为:,如下图所示: 点击 download 就可以下载配置文件,下载配置文件然后,复制配置文件中的内容粘贴到上图的粘贴内容处。 最后按上述方式就将配置文件导入到 Grafana 了。 最终的效果如下所示: 作者简介 陈厚道,曾就职于腾讯、盛大、斗鱼等互联网公司。目前就职于尚德机构,在尚德机构负责基础架构方面的设计和开发工作。对分布式消息队列、微服务架构和落地、DevOps 和监控平台有比较深入的研究。 冯庆,曾就职于华为。目前就职于尚德机构,在尚德机构基础架构团队负责基础组件的开发工作。 在 PC 端登录 知行动手实验室,沉浸式体验在线交互教程。 活动推荐 阿里云基于 Apache RocketMQ 构建的企业级产品消息队列RocketMQ 5.0版现开启活动: 1、新用户首次购买包年包月,即可享受全系列 85折优惠! 了解活动详情:
作者:陈厚道、冯庆
#技术探索 #可观测