共计 2636 个字符,预计需要花费 7 分钟才能阅读完成。
这篇文章给大家介绍如何基于 CloudEvent 实现服务目录集成,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
基于事件驱动的系统架构在日常的平台开发中早已司空见惯,通过消息队列进行事件的发送,然后分别构建对应的生产者和消费者。不过在传统的业务开发模式不同的事件会有不同的格式,不同的生产者生成出的事件格式也各不相同,消费者能消费的格式也是千差万别,本质上事件、生产者、消费者还是耦合的。那如何解决该问题呢?那就是我们今天要聊的 CloudEvent。
CloudEvent 简介
从官网的 CloudEvents 描述中我们可以看出,CloudEvent 本质上就是一个描述事件数据的规范。所以对于 CloudEvents 的学习有的时候,我们更多的应该是取理解其设计规范,而不是其所呈现出的数据结构形态。就像大家去学 tcp 协议一样,你不是去学的这个字段叫什么,而是要理解为什么会有这个字段,其解决的问题是什么。
如何解耦
对于 CloudEvents 的学习笔者采用自顶向下的方式来进行学习,即先去了解 CloudEvents 是如何在平台上进行事件、消费者、生产者的解耦,然后在去思考底层的相关字段的细节 一个事件的生命周期通常会包含生产、传输、消费三个环节,下面我们分别对这三个环节来进行介绍 cloudevent 与传统事件开发模式的区别。
事件生产
在传统的开发模式下不同的业务生产的的事件也各不相同,并且事件本身数据会相对较少,更多的是类似信号传递的角色,即通知后端服务某个类型事件发生了,然后由对应的系统构建事件的上下文数据,进行业务逻辑处理。而在 Cloudevents 中则更注重事件的一致性与完整性。为了保证事件可以被统一的分发、解析与处理,Cloudevents 采用了类似分层的事件封装机制,即 事件协议 与 事件数据 两层。事件协议是指 Cloudevent 定义了底层事件的格式,即大家都按照一套标准的规范来进行事件的封装,这样事件就可以被统一的处理和分发。而事件专有的数据则存储在对应的数据字段里面
完整性是我个人的理解,即我们在 Cloud 的环境中构建的事件需要包含其当前的完整上下文数据,以便后续系统有足够的信息可以进行业务逻辑处理与决策。这样可以避免后端系统在接收到事件后,需要进行当前事件对应上下文的组装,主要是解决由于传输存在的延迟导致相关数据可能已经不再是事件发生时的状态,存在状态不一致的情况
事件传输
事件产生后通常要发送到对应的消息代理服务进行暂存,在传统的业务中通常会选择特定的消息协议来进行传输,这中间通常会涉及两部分:序列化与传输协议。在传输协议中 Cloudevents 中支持常见的行业标准协议比如 HTTP、AMQP、MQTT、SMT 等,并支持常见的供应商与平台比如 kafka、AWS Kinesis、Azure 事件网格、Alibaba Cloud EventBridge,用户可以根据自己的场景选择对应的供应商分发对应的事件
在序列化方面 cloudevents 支持 HTTP、AMQP、Kafka 等常见的标准协议,而不需要用户手动进行相关协议的序列化
事件消费
事件的消费端通常会对其关注的事件类型感兴趣,并且由于消息的格式是统一的我们很容易就可以通过对应的平台来根据消息体里面的内容进行消息路由,分发给对应的事件消费者,事件的消费者只要负责对应事件的接收即可,而并不关注其他的信息
关于 Cloudevents 事件更多的内容,后面再继续分享,然后接下来就介绍下我们基于 cloudevent 是怎么设计系统的
入门场景
在前面的文章中,介绍过我们的服务目录系统,服务目录中要接入不同的基础服务,基础服务的格式各不相同,而且还要对接计费、效率统计等系统,后期可能还会对接公司的事件流平台,那如何对这些这些异构模块中异构的数据进行统一的分发和处理,我们的架构如下:
消息处理流程
首先在消息发送端,我们基于 cloudevent 构建对应的消息,并且将当前事件的上下文数据统一封装到 data 中,然后发送给公司的消息队列系统。由公司的消息队列来完成对应的事件分发与路由,对应的事件接收端只需要定义自己关注的事件,而不需要去监听具体的 MQ,只需要定义一个接受消息的 HTTP 接口接口,对应消息的路由与分发功能由公司的 MQ 来实现服务消费端解析消息队列传递过来的事件信息,解析出对应的数据结构,然后进行业务处理即可。后续如果增加模块,或者增加新的事件消费需求,只需要实现对应的逻辑即可
数据结构
结合 Cloudevents 的规范,我们定义自己内部的系统的数据结构。主要使用的结构如下:
这里主要介绍下我们附加的一些字段以及根据自己场景的定义:
type
从表面上看 Source 和 type 都描述了当前事件发生的系统,不同的是 type 中是一个结构化的数据,按照这个结构我们对应的计费、效率统计模块,就可以拿到这个数据去做相关一些支线逻辑的处理了。
resources:变更资源列表
即标识当前事件触发了哪些相关资源的改变,比如虚机添加硬盘,实际上是包含了两种资源即虚机与对应的磁盘资源
整合服务目录
前面提到我们使用服务和提供的 API 规范实现了一个服务代理模块,在服务代理模块中 Cloudevent 的主要使用场景如下:1. 服务目录接收到服务变更请求后,保存数据库后,发生对应的 cloudevent 事件到消息队列 2. 在消息队列中设定对应的路由转发规则,将对应的事件发生给服务代理模块 3. 服务代理模块根据 type 字段进行解析,获取对应的后端服务地址,并从消息中解析出对应的数据,将数据发送给后端真实的服务 4. 后端真实服务接收到结构化数据后,进行自己的业务逻辑处理,处理完成后发送对应的事件 5. 服务代理模块根据事件解析出相关的资源,调用对应的平台获取当前资源的数据,生成事件 6. 服务目录模块接收到对应的服务实例数据,存储到自己的数据库中
如果后续有变更则只需要产生对应的事件发生到消息队列中,会重复进行 5 - 6 阶段
链路虽然有点长,但其实整个链路的系统设计非常简单,系统之间的通信、可靠性、容错、耦合性都不需要关注(消息队列服务来保障),后续如果要扩展,就再怼个模块就可以了。要消费新的事件,就再写个新的接口,然后编辑下路由规则,就可以实现新的模块的接入了。
关于如何基于 CloudEvent 实现服务目录集成就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。