写点什么

组合式应用新利器?SaaS 新时代事件网格如何解决集成标准化问题

  • 2022 年 4 月 18 日
  • 本文字数:5511 字

    阅读完需:约 18 分钟

在 SaaS 新时代下,业务适应性需求引导企业转向支持快速、安全和高效应用变化的技术架构。组合式应用作为加速数字化的关键技术,是 Gartner 提出的在 2022 年重要战略技术之一,它由以业务为中心的模块化组件构建而成,使技术和业务团队可以更敏捷、更有效地重用代码。组合式应用需要面临的一个难题是如何解决各个应用之间的集成标准问题,比如应用可能仅支持 HTTP、TCP 等协议中的一种,而缺乏统一的通讯标准就给业务落地该架构带来了困难。下面介绍事件网格(EventGrid)是如何解决这一问题。


事件网格是华为云中间件在云原生时代推出的新一代无服务器事件总线,承载和管理来自传统应用、云服务应用和 SaaS 合作伙伴应用的各类事件,帮助应用开发者轻松搭建高可用、松耦合、分布式的事件驱动架构。作为 Serverless 架构下事件驱动架构的关键一环,它提供弹性、异步、去中心化的事件治理服务,对事件提供汇聚、模型校验、过滤、路由、转换和推送等核心功能,还包括容错重试、死信储存、事件查询跟踪、事件工作流等增强特性。

从以上 EventGrid 总体架构图可以看出,EventGrid 对接了一系列云服务作为事件源。这些云服务包括分布式消息服务(如 RocketMQ、Kafka 和 Pulsar)、对象存储服务 (OBS) 和分布式缓存服务(Redis) 。事件源会产生管理类、数据类和自定义事件,然后通过 EventGrid SDK 推送到 EventGrid 的事件总线 (Bus Runtime) 的 事件通道中。事件总线为 EventGrid 用户以租户为单位配置事件通道,一个租户下允许有多个事件通道,承载来自不同事件源的事件。比如默认事件通道存储华为云产生的事件,而自定义事件通道存储应用和微服务的事件。EventGrid 用户通过订阅的方式消费事件,通过在订阅的配置项里定义事件源、事件目标、事件过滤和转换规则,EventGrid 就能从事件总线里提取相关事件,然后实时推送到所定义的事件目标中。推送方式可以是同步和异步:同步推送一般是以 HTTP 协议,适合应用和微服务;异步推送一般是推动到 SaaS 伙伴应用的消息队列中。


所以,华为云 EventGrid 通过事件驱动的方式联动周边的云服务、云原生应用和 SaaS 伙伴应用,实现服务和应用之间解耦,专注发挥自己服务的优势,通过各种事件模型连接,为华为云创造更多的应用场景,丰富华为云的开发者生态。

以 EventMesh 为引擎

华为云 EventGrid 引入了开源明星项目 Apache EventMesh,作为其运行时引擎。Apache EventMesh 作为云原生的事件驱动架构中间件,用于分离应用程序和后端事件存储(Event Store),支持广泛的应用场景,包括混合云和传统数据中心,以及不同技术栈的分布式架构。


Apache EventMesh 的理念和 EventGrid 很类似。它也是连接事件源,聚集事件,然后把事件推送到客户端。它的亮点是其内核可以支持插件化。根据不同的事件应用场景,可以接入不同的插件来匹配。比如在事件链接器 (Event Connector)方面, 可以对接 RocketMQ Connector 或者 Kafka Connector。在 HTTP 授权(Http-Auth)方面, 可以引用 BasicAuth 或者 TokenAuth。 这样灵活的架构有助于打造生态系统,对接不同的产品和服务。

EventMesh gRPC 特性

Apache EventMesh 最新发布的 v1.4.0 版本相比之前的版本又增加了多个重要特性和架构优化。其中一个亮点是对于 gRPC 的支持。gRPC 是基于 HTTP/2 的现代高性能 RPC (Remote Procedure Call) 框架。相比 HTTP 协议,gRPC 支持 Client 和 Server 双向异步通讯,通过 Protobuf 定义 API 接口数据模型,支持多语言 SDK。 通过实现 gRPC 协议,Apache EventMesh 可以整合原有的 TCP 和 HTTP 协议,让当前运行时轻量化。 同时其 SDK 可以扩展到多语言支持,比如 Java、Go、JavaScript 等等。

Protobuf 设计

EventMesh 引入 gRPC 首先从设计 Protobuf 定义(eventmesh-client.proto) 开始。我们在 eventmesh-client.proto 文件里定义 EventMesh 事件发送和订阅服务的方法和事件模型。由于篇幅原因,以下仅介绍定义的重点部分,完整的文档请见:

https://github.com/apache/incubator-eventmesh/blob/master/eventmesh-protocol-plugin/eventmesh-protocol-grpc/src/main/proto/eventmesh-client.proto

1、事件发送服务提供以下接口。

service PublisherService {    rpc publish(SimpleMessage) returns (Response);
rpc requestReply(SimpleMessage) returns (SimpleMessage);
rpc batchPublish(BatchMessage) returns (Response);}
复制代码

事件是以 SimpleMessage 的数据模型呈现。事件发送支持同步发送、异步发送和批量发送三种模式。其中同步发送是指事件生产者发送事件到 EventMesh,并等待事件成功推送到事件消费者,并收到事件消费者的返回,才算完成整个端到端的事件发送过程;异步发送是指事件生产者发送事件到 EventMesh 即可,无需等待事件被成功推送到事件消费者;批量发送是指异步发送一批事件到 EventMesh。


2、事件模型如下:

message RequestHeader {    string env = 1;    string region = 2;    string idc = 3;    string ip = 4;    string pid = 5;    string sys = 6;    string username = 7;    string password = 8;    string language = 9;    string protocolType = 10;    string protocolVersion = 11;    string protocolDesc = 12;}
message SimpleMessage { RequestHeader header = 1; string producerGroup = 2; string topic = 3; string content = 4; string ttl = 5; string uniqueId = 6; string seqNum = 7; string tag = 8; map<string, string> properties = 9;}
复制代码

事件模型可以支持多种协议,包括 CNCF CloudEvents、OpenMessenging 和 EventMesh 原生事件协议,这些协议都在 SimpleMessage 的 protocol 相关字段中体现。 另外模型中带有 producerGroup 和 topic 用于事件的路由;ttl、uniqueId 和 seqNum 则是用于事件的管理。请求头里带有事件生产者的基本信息: env、region、idc、ip 和 sys。


3、事件订阅服务提供以下接口:

service ConsumerService {
rpc subscribe(Subscription) returns (Response);
rpc subscribeStream(stream Subscription) returns (stream SimpleMessage);
rpc unsubscribe(Subscription) returns (Response);}
复制代码

事件订阅支持两种方式:集群(cluster) 和广播(broadcast) 。集群模式中,事件消费者集群里只有一个实例能消费到事件;广播模式让集群里每一个实例都消费到事件。这些订阅模式是在订阅数据模型里定义的。另外订阅服务提供两种订阅接口:subscribe API 和 subscribeStream API。Subscribe API 是通过 url 方式 推送事件到消费者,这里 url 又叫 webhook。这种场景适合云原生微服务和自定义应用及函数。


subscribeStream API 是通过 gRPC 双向流(Bidirectional Streaming) 推送事件到消费者 ,同时可以让事件消费者返回确认信息 (Ack) 给事件生产者。这就满足了生产者 RequestReply 同步事件发送的需求。

服务端的多线程并发

为了提高事件生产和消费的性能,EventMesh 服务端 (EventMesh Runtime) 在 gRPC 的服务里定义了线程池 (ThreadPool),而且针对事件生产和消费的对性能要求的不同,配置独立的参数。这些参数都可以在 EventMesh 配置文件 (eventmesh.properties)里找到。比如以下分别是事件生产,订阅和推送的线程数。

eventMesh.server.sendmsg.threads.num=50eventMesh.server.clientmanage.threads.num=30eventMesh.server.pushmsg.threads.num=50
复制代码

当 gRPC 服务启动后,它会监听客户端的请求,一旦有新请求进来,它会分发到对应服务的线程池,然后让对应的处理器 (Processor)处理,这样就不会阻塞下一个请求的处理,从而提高了并发量。

public void publish(SimpleMessage request, StreamObserver<Response> responseObserver){    cmdLogger.info("cmd={}|{}|client2eventMesh|from={}|to={}", "AsyncPublish",        EventMeshConstants.PROTOCOL_GRPC, request.getHeader().getIp(),        eventMeshGrpcServer.getEventMeshGrpcConfiguration().eventMeshIp);
EventEmitter<Response> emitter = new EventEmitter<>(responseObserver);
threadPoolExecutor.submit(() -> { SendAsyncMessageProcessor sendAsyncMessageProcessor = new SendAsyncMessageProcessor(eventMeshGrpcServer); try { sendAsyncMessageProcessor.process(request, emitter); } catch (Exception e) { logger.error("Error code {}, error message {}", StatusCode.EVENTMESH_SEND_ASYNC_MSG_ERR.getRetCode(), StatusCode.EVENTMESH_SEND_ASYNC_MSG_ERR.getErrMsg(), e); ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_SEND_ASYNC_MSG_ERR, e.getMessage(), emitter); } });}
复制代码

比如以上代码是事件发送服务 (publish service) 的实现。它使用了 threadPoolExecutor 把事件发送到线程池让下游 SendAsyncMessageProcessor 处理。

事件消费者的负载均衡和重试

在事件消费者方面,EventMesh 支持负载均衡。用户可以在事件订阅里指定多个事件消费者来消费事件。每个消费者会是一个 URL(Webhook) 或者 gRPC 客户端 (stream),这些消费者可以是集群或者是主备方式部署。那么 EventMesh 会通过算法计算选择其中一个消费者去推送事件。如果当前消费者无法消费事件,那么 EventMesh 会选下一个消费者。EventMesh 默认以轮询方式选择消费者推送事件,来达到消费者的负载均衡。开发者可以通过插件提供其他算法来选择消费者。


事件推送失败,可能是网络原因,当前消费者繁忙或下线。EventMesh 先尝试重试,每次重试会间隔几秒钟,最多重试 3 次。如果 3 次重试失败了,EventMesh 才会选择下一个消费者。重试间隔时间可以在配置文件里定义。

gRPC non-Blocking 和 Blocking Stub

为了提高客户端性能,gRPC 提供了非阻塞存根 (non-Blocking Stub)。使用 non-Blocking Stub 客户端发送请求后不需要等待服务器回复,继续进行执行下一步操作。这很适合在大量事件生产的场景。但是在事件 RequestReply 场景下,客户端需要同步的等待事件成功推送到事件消费者,我们就需要 gRPC 的阻塞存根 (Blocking Stub)。通过给客户端提供的两种选择,可以更灵活的满足不同的事件生产和消费场景。目前 EventMesh SDK 使用了 Blocking Stub, 下一步是使用 non-Bocking Stub 提高客户端高并发性能。

支持多语言 SDK

Apache EventMesh v1.3.0 之前只提供 Java SDK。这对于接入其他云原生的应用场景有局限。因为很多云服务都是用 Go, Python 和 JavaScript (NodeJS 框架) 语言开发的 。一些云原生的开源项目,比如 KNative、Dapr 也是用 Go 作为开发语言。所以 EventMesh 对支持多语言 SDK 有迫切需求,以继续丰富应用开发者的生态。


gRPC 的开发工具带有多语言代码生成工具,包括 Java、Go、NodeJS、PHP、Python、C#和 C++等。EventMesh 实现 gRPC 协议后可以借助该工具,快速提供多语言的 SDK。后续对于通信 API 的改动只需要同步修改 Protobuf 模型定义,重新生成代码即可。迭代快速,维护简单。

整合 TCP 和 HTTP 协议

gRPC 支持 4 种 Client 和 Server 通信 RPC 机制:Unary RPC、Server Streaming RPC、Client Streaming RPC 和 Bidirectional Streaming RPC. EventMesh v1.4.0 版本整合了 v1.3.0 版本的 TCP 和 HTTP 的 SDK API,利用 Unary RPC 和 Bidirectional Streaming RPC,提供了 Event Publish、Broadcast、Request-Reply、Webhook Subscription 和 Event Stream Subscription 五种 SDK API。

通过整合 TCP 和 HTTP 协议,EventMesh Runtime 和 SDK 架构更加轻量化,减少了代码维护。同时用户使用 SDK 就不需要考虑使用场景要选哪一种协议。用户不需要学习和感知 SDK 层面的通讯协议,gRPC 就能满足他们事件生产和消费的所有场景。

开箱即用的 gRPC 样例

为了让 EventMesh 开发者更好的体验 gRPC 新特性,社区提供了完善的使用文档和多个 Event Publisher, Event Subscriber 代码样例。以下是相关文档:


https://github.com/apache/incubator-eventmesh/blob/master/docs/en/instructions/eventmesh-runtime-quickstart.md

https://github.com/apache/incubator-eventmesh/blob/master/docs/en/instructions/eventmesh-sdk-java-quickstart.md


第一个文档介绍如何部署和启动 EventMesh 服务器。文档里第一部分介绍如何远程部署 EventMesh 在虚拟机里,适合测试和生产环境的部署;第二部分介绍如何在本地开发环境里部署 EventMesh,适合常用的本地开发和调试场景。以下命令行是展示如何在 Linux 环境里部署和启动 EventMesh Runtime

> tar -zxvf Eventmesh_1.3.0-release.tar.gz> cd bin> sh start.sh> tail -f ./logs/eventmesh.out
复制代码

第二个文档介绍如何使用 EventMesh SDK 开发应用生产和消费事件,包含了 TCP、HTTP 和 gRPC 三部分。EventMesh 工程项目里带有客户端的代码样例 (eventmesh-example),包括了 gRPC Event Publisher、Event Subscriber 的代码。比如,我们可以把 EventMesh 工程项目导入 Java IDE 里 (比如 Intellij IDEA)。按照以下步骤启动 gRPC Event Publisher and Subscriber。


1. 修改 eventmesh-examples/src/main/resources/application.properties 指向已经部署的 EventMesh Runtime。

2. 启动 Event Publisher, 运行

Eventmesh-example/src/main/java/org.apache.eventmesh.grpc.pub.eventmeshmessage.AsyncPublishInstance
复制代码


3. 启动 Event Subscriber, 运行

Eventmesh-example/src/main/java/org.apache.eventmesh.grpc.sub.app.SpringBootDemoApplication
复制代码


作为组合式应用新利器,gRPC 的引入无疑是集成标准化的一大助力。当然,除了通讯标准外,还有 schema、governance 等集成标准需要统一,事件网格会在这些领域继续做出自己的探索。


点击关注,第一时间了解华为云新鲜技术~

发布于: 刚刚阅读数: 5
用户头像

提供全面深入的云计算技术干货 2020.07.14 加入

华为云开发者社区,提供全面深入的云计算前景分析、丰富的技术干货、程序样例,分享华为云前沿资讯动态,方便开发者快速成长与发展,欢迎提问、互动,多方位了解云计算! 传送门:https://bbs.huaweicloud.com/

评论

发布
暂无评论
组合式应用新利器?SaaS新时代事件网格如何解决集成标准化问题_Serverless_华为云开发者社区_InfoQ写作平台