1.4.3 事件总线
本节将介绍AWS的EventBridge及开源的事件规范CloudEvent。
1.4.3.1 云服务事件总线EventBridge
ESB(企业服务总线)是SOA时代用于解决不同应用系统对接的事件总线服务,提供应用系统的服务接入、协议转换、可靠的消息传输、编码格式转换、请求路由等功能。ESB作为消息中间件,可以实现业务系统的松耦合,提供异步消息处理机制。
进入Serverless时代后,遇到了与SOA时代同样的问题。
• 事件源多:云服务商需要接入自身平台、第三方平台的SaaS服务或其他事件源。
• 事件目的地多:这些事件源可能需要对接不同的Serverless服务,比如对于用户订购商品成功的事件,需要将其发送到短信通知的Serverless 服务(如AWS SNS),以及分析的服务(如AWS Kinesis)。
• 需要对事件进行过滤或转换:不愿意接收消息推送的用户,不应该接收到消息。
如果没有类似ESB的总线服务,无论是云服务商还是用户,都需要编写大量的胶水转换代码,同时还要完成部署并保证这些代码在运行时中的可靠性,这增加了开发者的成本。
为此,云服务商推出了事件总线服务EventBridge。例如,AWS的由EventBridge全托管的事件总线,通过Schema定义EventBridge可对接异构事件源及目标,支持扇入/扇出(Fan-in/Fan-out),也支持事件过滤和路由。所有事件源只需要统一对接到EventBridge即可。
如图1-25所示,开发者将Schema以配置文件的形式发送到EventBridge中,定义好过滤规则、事件的目的地。事件源(AWS服务或其他SaaS服务)可以使用Webhook或集成EventBridge的客户端向EventBridge发送消息。EventBridge接收到请求后,可以针对事件进行过滤、路由,再去触发AWS的自有Serverless服务或第三方服务(自定义或第三方的事件总线)。
图1-25 AWS EventBridge逻辑架构(详见官方文档)
EventBridge可以解决单个云服务商的事件源和目的服务解耦的问题,如果开发者需要跨多个云,在没有统一的事件规范前提下,开发者同样要使用胶水代码进行事件格式或协议转换。此外,事件数据往往可能涉及多跳环节,使用多个协议并跨多个云的系统才能完成处理。如图1-26所示,对IoT设备的告警,可将正常业务事件及遥测事件通过网关发送给不同的处理者,由它们经过不同的流程完成处理。对于运行过程中不同的云服务,用户需要使用专门的胶水代码来进行消息转换。因此,开发者需要通用的方式去描述事件,这是CloudEvents规范产生的动因。
图1-26 事件数据可能通过不同协议和编码在不同的系统间传播(详见官方文档)
1.4.3.2 事件规范CloudEvents
CloudEvents是CNCF在2017年推出的一个轻量级的事件规范,目前有超过30家公司参与制定。CloudEvents规范集成了一组大多数事件已经定义的基础公共元数据属性,如唯一ID、事件从哪里来、生成事件的事件类型和内容等。
如图1-27所示,CloudEvents没有重复“造轮子”,而是集成和兼容现有的协议。它集成现有消息和事件的技术栈(如Kafka、NATS等),并在现有的编码(序列化)基础上,使不同格式的编码(如Protobuf、JSON等)更容易对接。CloudEvents允许在编码过程中更换编码格式和协议,以满足事件可能经过多跳路由的场景。
图1-27 CloudEvents支持多种编码方式(详见官方文档)
CloudEvents定义了四种不同的元素,包括核心属性(基础的上下文、事件属性键值对)、扩展属性(自定义属性键值对)、事件格式(如JSON)及绑定的协议(HTTP、Kafka等)。
CloudEvents事件的编码支持两种模式。
• 二进制模式可以适应任何形式的事件数据,可以高效传输,无须转码。
• 结构化模式将事件的元数据和数据都放在请求内容中,方便跨多个协议转发。
下面CloudEvents文档中的样例代码基于HTTP协议,分别使用二进制及结构化方式发送CloudEvents事件。
当前,已经有多个云平台,如Azure的Event Grid、阿里云的Event Bridge、GCP的Eventarc,支持CloudEvents,CloudEvents自身也提供了对主流事件编码的兼容及对多语言客户端的支持。