CloudEvents 基础

CloudEvents 概念

CloudEvents规范最初由CNCF旗下的Serverless Working group创建,但自v0.1之后,该规范即被提升为一个独立CNCF沙箱项目。常用于分布式系统环境,帮助用户构建松散耦合且可独立部署的分布式系统。为行业订立一个规范以提升互操作性

CloudEvents 事件

事件包括某个实际情景(occurrence)的上下文和数据,以及一个惟一标识;
事件通常用于后端代码中,负责连接不同的代码块(子系统),其中一个代码块的状态变动会触发另一个代码块的运行;
事件源(source)生成的事件(Event)被封装在协议中生成传输单元(message)以方便传输;事件到达目的端后,将触发基于事件数据的动作(action);
1. 传输协议:支持行业的各种标准协议(如HTTP、AMQP、MQTT和SMTP等)、开源协议(如Kafka和NATS),以及平台/供应商的特有协议;
2. 动作通常是由特定来源的特定事件触发,是专门负责处理该类事件代码块,这些代码块可运行于Serverless Function逻辑中;

CloudEvents 术语

Occurrence/事件发生

“事件发生”是指在软件系统运行期间对事实状态的捕获。 这可能是由于系统发出了信号或系统观察到信号、状态更改、计时器超时 或任何其他值得注意的活动而发生的。 例如,设备可能会因为电池电量低或虚拟机即将执行计划的重启而进入警报状态。

Event/事件

“事件”是表示一条"发生"及其上下文的数据记录。 事件从事件生产者(源)路由到对它感兴趣的事件消费者。 事件中包含的信息帮助完成路由操作,但事件不会标识特定的路由目的地。 事件将包含两种类型的信息:表示"发生"的事件数据 和提供有关事件的环境信息的上下文元数据。 一次"发生"可能导致多个事件的产生。

Producer/生产者

“生产者”是一种特定的实例、进程或设备,它创造了用来描述 CloudEvent 这个事件的数据结构。

Source/源

"源"是事件发生的上下文环境。在分布式系统中,它可能由多个生产者组成。 如果一个源无法查看到 CloudEvents,那么一定有有外部的生产者在代替源来生产 CloudEvent。

Consumer/消费者

一个“消费者”会接收事件并根据事件采取一定的行为。 它使用上下文环境和事件数据来执行一些逻辑,这可能会导致新事件的发生。

Intermediary/中间人

一个“中间人”会接收包含事件的消息,并将其转发给下一个接收者,但该接收者可能是另一个中间人或事件消费者。 中间人的典型任务就是根据上下文环境中的信息将事件路由到接收者。

Context/上下文

上下文环境元数据被封装在上下文-属性中。 工具和应用程序代码可以使用此信息来识别事件与系统方面或事件与其他事件的关系。

Data/数据

Data 描述的是关于"事件发生"的特定域信息(即有效负载)。这可能包括有关“事件发生”的信息、有关已更改数据的详细信息等。 

Event Format/事件格式

一个事件格式会指定如何将 CloudEvent 序列化为字节序列。 独立事件格式(例如 JSON 格式)指定独立于任何协议或存储介质的序列化。 协议绑定可以定义依赖于协议的格式。

Message/消息

事件通过消息从源传输到目标。 “结构化模式消息”是一种将事件进行完全编码并存储在消息体中的消息。 “二进制模式消息”会将事件数据存储在消息体中,并将事件属性作为消息元数据的一部分存储下来。

Protocol/协议

消息可以通过各种行业标准协议(例如 HTTP、AMQP、MQTT、SMTP)、开源协议(例如 Kafka、NATS)或平台/供应商 专有协议(例如 AWS Kinesis、Azure 事件网格)传输。

Protocol Binding/协议绑定

协议绑定描述了如何通过给定的协议发送和接收事件。

协议绑定可以选择使用事件格式,将事件直接映射到传输包的正文,或者可以为包提供额外的格式和结构。 例如,可以使用结构化模式消息的包装器,或者可以将多个消息一起批处理到传输包正文中。

CloudEvents core规范中的事件格式

CloudEvents core规范包含一组称为属性的元数据,用于指明如何在系统之间传输事件,以及这些元数据应该如何出现在消息(传输报文)中。

Context Attributes/上下文属性

必要属性

id/标识

类型: String

描述: 标识一个事件。 生产者必须确保每个不同事件的 source + id 是唯一的。 如果重复的事件被重新发送(例如由于网络错误),它可能具有相同的 id。 消费者可以假设具有相同 source 和 id 的事件是重复的。

约束条件:
  必要的
  必须是非空字符串
  在生产者的范围内必须是唯一的

示例:
  一个由生产者维护的事件计数器
  一个 UUID

source/事件源

类型: URI-reference

描述: 标识事件发生的上下文背景。 这通常包括诸如事件源类型、发布事件的组织 或产生事件的过程等信息。URI 中编码的数据背后的确切语法和语义由事件生产者定义。
  生产者必须确保每个不同事件的 source + id 是唯一的。
  应用程序可以为每个不同的生产者分配一个唯一的 source, 这使得生成唯一 ID 变得容易,因为没有其他生产者将拥有相同的来源。 应用程序可以使用 UUIDs、URNs、DNS权威机构或特定于应用程序的方案来创建唯一的 source 标识符。
  一个来源可以包括多个生产者。 在这种情况下,生产者必须协作以确保每个不同事件的 source + id 都是唯一的。

约束条件:
  必要的
  必须是非空 URI-reference
  推荐使用 绝对 URI
  
示例
  具有 DNS 权限的 Internet 范围唯一 URI:
    https://github.com/cloudevents
    mailto:cncf-wg-serverless@lists.cncf.io
  具有 UUID 的通用唯一 URN:
    urn:uuid:6e8bc430-9c3a-11d9-9669-0800200c9a66
  应用程序专有的标识符
    /cloudevents/spec/pull/123
    /sensors/tn-1234567/alerts
    1-555-123-4567

specversion/规范版本

类型: String

描述: 事件使用的 CloudEvents 规范的版本。 这让解释上下文环境更容易。 当引用这个版本的规范时,兼容的事件生产者必须使用 1.0 的值。
  目前,此属性仅包含“主要”和“次要”版本号。这允许对规范进行“补丁”更改,而无需更改序列化中此属性的值。 注意:对于“候选发布”版本,后缀可能用于测试目的。

约束条件:
  必要的
  必须是非空字符串

type/类型

类型: String

描述: 该属性包含一个值,描述与原始事件相关的事件类型。 该属性通常用于路由、可观察性、策略实施等。其格式是生产者定义的,可能包括诸如 type 版本之类的信息。 

约束条件:
  必要的
  必须是非空字符串
  应该以反向 DNS 名称作为前缀。该前缀域表明了定义此事件类型语义的组织。
  
示例
  com.github.pull_request.opened
  com.example.object.deleted.v2

可选属性

datacontenttype/data内容类型

类型: String RFC 2046

描述: data 值的内容类型。 此属性使 data 能够承载任何类型的内容, 因此格式和编码可能与所选事件格式的不同。 例如,使用 JSON envelope格式呈现的事件可能在数据中携带 XML 的有效负载,这个属性可以用来通知消费者 设置"application/xml"。 关于 data 内容如何提供不同的 datacontenttype 的值的规则在事件格式规范中定义。 例如,JSON 事件格式定义了 3.1 节中的关系。
  对于某些二进制模式协议绑定,此字段直接能映射到相应协议的内容类型的元数据属性上。 二进制模式和内容类型元数据映射的规范规则可以在各自的协议中找到。
  在某些事件格式中,可以省略 datacontenttype 属性。 例如,如果 JSON 格式的事件没有 datacontenttype 属性, 则表示该 data 是符合“application/json”媒体类型的 JSON 值。 换句话说:一个没有 datacontenttype 的 JSON 格式的事件完全等同于 一个带有 datacontenttype="application/json" 的事件。
  当将没有 datacontenttype 属性的事件消息转换为不同的格式或协议绑定时, 目标 datacontenttype 应该显式设置为事件源的隐含或默认的 datacontenttype。

约束条件:
  可选的
  若有则必须遵守 RFC 2046 制定的格式

dataschema/数据模式

类型: URI

描述: 标识 data 遵守的规范。 对模式的不兼容的更改应该由不同的 URI 体现。

约束条件:
  可选的
  若有必须是非空的 URI

subject/主题

类型: String

描述: 这个属性描述了事件生产者 (由 source 标识) 上下文环境中的主题信息。 在发布-订阅场景中,订阅者通常会订阅 source 发出的事件, 但如果 source 的上下文环境具有内部子结构, 则单独的 source 标识符可能不足以作为任何指定事件的限定符。
   当中间件无法解释 data 内容时,在上下文元数据中识别事件的主题(相对于仅仅在 data 负载中)在通过订阅过滤场景中特别有用。 在上面的示例中,订阅者可能仅仅对blobs中名字以 .jpg 或者 .jpeg 结尾和可以为该事件子集构建一个简单有效的字符串后缀过滤器的 subject 属性感兴趣。

约束条件:
  可选的
  若有必须是非空字符串

示例:
  订阅者可能对在 blob 在 blob 存储容器中创建的时候感兴趣并订阅。 在这个场景下,事件 source 标示出订阅的范围(存储容器),type 标识出 blob 创建" 这个事件,id 唯一标识出事件示例,以区分已创建同名 blob 的事件, 而新创建的 blob 的名字可以放在 subject 属性中:
    source: https://example.com/storage/tenant/container
    subject: mynewfile.jpg

time/时间

类型: Timestamp

描述: 事件发生的时间戳。 如果无法确定发生的时间,则 CloudEvents 生产者可以将此属性设置为其他时间(例如当前时间)。 但是在这方面,同一 source 的所有生产者必须保持一致。 换句话说,要么它们都使用发生的实际时间,要么它们都使用相同的算法来确定所使用的值。

约束条件:
  可选的
  若有则必须遵守 RFC 3339

示例

☁️  cloudevents.Event
Validation: valid
Context Attributes,
  specversion: 1.0
  type: dev.knative.eventing.samples.heartbeat
  source: https://knative.dev/eventing/cmd/heartbeats/#event-test/mypod
  id: 2b72d7bf-c38f-4a98-a433-608fbcdd2596
  time: 2019-10-18T15:23:20.809775386Z
  contenttype: application/json
Extensions,
  beats: true
  heart: yes
  the: 42
Data,
  {
    "id": 2,
    "label": ""
  }

CloudEvents 中的序列化规范

CloudEvents还提供了如何以不同格式(如JSON)和协议(如HTTP、AMQP和Kafka)等将事件进行序列化的规范。
CloudEvents还定义了一组Adapter规范,以便于帮助用户构建Adapter,从而将那些非CloudEvents规范的事件转为CloudEvents格式;

HTTP 二进制内容模式

1. Content-Type标头:负责代表CloudEvents中的datacontenttype属性
2. 报文的Body部分代表CloudEvents中Data属性中的事件数据
3. CloudEvents中的其它属性字段,必须各自映射为报文中标头,例如id要定义为“ce-id”标头;

示例

此示例显示事件与 HTTP POST 请求的二进制模式映射:
POST /someresource HTTP/1.1
Host: webhook.example.com
ce-specversion: 1.0
ce-type: com.example.someevent
ce-time: 2018-04-05T03:56:24Z
ce-id: 1234-1234-1234
ce-source: /mycontext/subcontext
    .... further attributes ...
Content-Type: application/json; charset=utf-8
Content-Length: nnnn

{
    ... application data ...
}
此示例显示包含事件的响应:
HTTP/1.1 200 OK
ce-specversion: 1.0
ce-type: com.example.someevent
ce-time: 2018-04-05T03:56:24Z
ce-id: 1234-1234-1234
ce-source: /mycontext/subcontext
    .... further attributes ...
Content-Type: application/json; charset=utf-8
Content-Length: nnnn

{
    ... application data ...
}

HTTP 结构化内容模式

1. Content-Type标头:使用application/cloudevents
2. 其它部分以json格式的body数据提供

示例

此示例显示了使用 PUT 请求发送的 JSON 事件格式编码事件:
PUT /myresource HTTP/1.1
Host: webhook.example.com
Content-Type: application/cloudevents+json; charset=utf-8
Content-Length: nnnn

{
    "specversion" : "1.0",
    "type" : "com.example.someevent",

    ... further attributes omitted ...

    "data" : {
        ... application data ...
    }
}
此示例显示响应中返回的 JSON 编码事件:

HTTP/1.1 200 OK
Content-Type: application/cloudevents+json; charset=utf-8
Content-Length: nnnn

{
    "specversion" : "1.0",
    "type" : "com.example.someevent",

    ... further attributes omitted ...

    "data" : {
        ... application data ...
    }
}

HTTP 批量内容模式

在批处理内容模式中,多个事件被批处理到单个 HTTP 请求或响应正文中。所选事件格式必须定义批次的表示方式,包括合适的媒体类型。

示例

此示例显示了两个批处理的 CloudEvents,通过 PUT 请求发送:

PUT /myresource HTTP/1.1
Host: webhook.example.com
Content-Type: application/cloudevents-batch+json; charset=utf-8
Content-Length: nnnn

[
    {
        "specversion" : "1.0",
        "type" : "com.example.someevent",

        ... further attributes omitted ...

        "data" : {
            ... application data ...
        }
    },
    {
        "specversion" : "1.0",
        "type" : "com.example.someotherevent",

        ... further attributes omitted ...

        "data" : {
            ... application data ...
        }
    }
]
此示例显示响应中返回的两个批处理的 CloudEvents:

HTTP/1.1 200 OK
Content-Type: application/cloudevents-batch+json; charset=utf-8
Content-Length: nnnn

[
    {
        "specversion" : "1.0",
        "type" : "com.example.someevent",

        ... further attributes omitted ...

        "data" : {
            ... application data ...
        }
    },
    {
        "specversion" : "1.0",
        "type" : "com.example.someotherevent",

        ... further attributes omitted ...

        "data" : {
            ... application data ...
        }
    }
]

参考文档

https://cloudevents.io/

posted @ 2023-10-12 17:49  小吉猫  阅读(547)  评论(0编辑  收藏  举报