定义无处不在的事件 - CloudEvent

本文涉及的产品
Serverless 应用引擎 SAE,800核*时 1600GiB*时
应用实时监控服务ARMS - 应用监控,每月50GB免费额度
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: Event 事件无处不在,然而每个事件提供者产生的事件各不相同。由于缺乏事件的统一描述,对于事件的开发者来说需要不断的重复学习如何消费不同类型的事件。这也限制了类库、工具和基础设施在跨环境(如 SDK、事件路由或跟踪系统)提供事件数据方面的潜力。从事件数据本身实现的可移植性和生产力上受到了阻碍。本文将为大家详细介绍 CloudEvent 的相关内容。

本文选自《Knative 云原生应用开发指南》
knative海报.png
更多云原生技术资讯可关注阿里巴巴云原生技术圈

背景

Event 事件无处不在,然而每个事件提供者产生的事件各不相同。由于缺乏事件的统一描述,对于事件的开发者来说需要不断的重复学习如何消费不同类型的事件。这也限制了类库、工具和基础设施在跨环境(如 SDK、事件路由或跟踪系统)提供事件数据方面的潜力。从事件数据本身实现的可移植性和生产力上受到了阻碍。

什么是 CloudEvents

CloudEvents 是一种规范,用于以通用格式描述事件数据,以提供跨服务、平台和系统的交互能力。
事件格式指定了如何使用某些编码格式来序列化 CloudEvent。支持这些编码的兼容 CloudEvents 实现必须遵循在相应的事件格式中指定的编码规则。所有实现都必须支持 JSON 格式。

协议规范

命名规范

CloudEvents 属性名称必须由 ASCII 字符集的小写字母(“a”到“z”)或数字(“0”到“9”)组成,并且必须以小写字母开头。属性名称应具有描述性和简洁性,长度不应超过20个字符。

术语定义

本规范定义如下术语:

  • Occurrence: “Occurrence”是指在软件系统运行期间捕获描述信息。
  • Event: "Event" 是表示事件及其上下文的数据记录。
  • Context:  Context 表示上下文,元数据将封装在 Context 属性中。应用程序代码可以使用这些信息来标识事件与系统或其他事件之间的关系。
  • Data: 实际事件中有效信息载荷。
  • Message: 事件通过 Message 从数据源传输到目标地址。
  • Protocol: 消息可以通过各种行业标准协议(如http、amqp、mqtt、smtp)、开源协议(如kafka、nats)或平台/供应商特定协议(aws-kineis、azure-event-grid)进行传递。

上下文属性(Context Attributes)

符合本规范的每个 CloudEvent 必须包括根据需要指定的上下文属性,并且可以包括一个或多个可选的上下文属性。
参考示例:

specversion: 0.2
  type: dev.knative.k8s.event
  source: /apis/serving.knative.dev/v1alpha1/namespaces/default/routes/sls-cloudevent
  id: 269345ff-7d0a-11e9-b1f1-00163f005e02
  time: 2019-05-23T03:23:36Z
  contenttype: application/json
  • type: 事件类型, 通常此属性用于路由、监控、安全策略等。
  • specversion: 表示 CloudEvents 规范的版本。引用 0.2 版本的规范时,事件生产者必须使用 0.2 设置此值。
  • source:表示事件的产生者, 也就是事件源。
  • id: 事件的 id
  • time: 事件的产生时间
  • contenttype: 表示Data 的数据内容格式

扩展属性(Extension Attributes)

CloudEvents 生产者可以在事件中包含其他上下文属性,这些属性可能用于与事件处理相关的辅助操作。

Data

正如术语Data所定义的,CloudEvents 产生具体事件的内容信息封装在数据属性中。例如,KubernetesEventSource所产生的 CloudEvent 的Data信息如下:

data:
  {
    "metadata": {
      "name": "event-display.15a0a2b54007189b",
      "namespace": "default",
      "selfLink": "/api/v1/namespaces/default/events/event-display.15a0a2b54007189b",
      "uid": "9195ff11-7b9b-11e9-b1f1-00163f005e02",
      "resourceVersion": "18070551",
      "creationTimestamp": "2019-05-21T07:39:30Z"
    },
    "involvedObject": {
      "kind": "Route",
      "namespace": "default",
      "name": "event-display",
      "uid": "31c68419-675b-11e9-a087-00163e08f3bc",
      "apiVersion": "serving.knative.dev/v1alpha1",
      "resourceVersion": "9242540"
    },
    "reason": "InternalError",
    "message": "Operation cannot be fulfilled on clusteringresses.networking.internal.knative.dev \"route-31c68419-675b-11e9-a087-00163e08f3bc\": the object has been modified; please apply your changes to the latest version and try again",
    "source": {
      "component": "route-controller"
    },
    "firstTimestamp": "2019-05-21T07:39:30Z",
    "lastTimestamp": "2019-05-26T07:10:51Z",
    "count": 5636,
    "type": "Warning",
    "eventTime": null,
    "reportingComponent": "",
    "reportingInstance": ""
  }

实现

以 Go SDK 实现 CloudEvent 0.2 规范为例:

事件接收服务

  • 导入cloudevents
import "github.com/cloudevents/sdk-go"

-通过 HTTP 协议接收 CloudEvent 事件

func Receive(event cloudevents.Event) {
    fmt.Printf("cloudevents.Event\n%s", event.String())
}

func main() {
    c, err := cloudevents.NewDefaultClient()
    if err != nil {
        log.Fatalf("failed to create client, %v", err)
    }
    log.Fatal(c.StartReceiver(context.Background(), Receive));
}

事件发送服务

  • 创建一个基于  0.2 协议的 CloudEvent 事件
event := cloudevents.NewEvent()
event.SetID("ABC-123")
event.SetType("com.cloudevents.readme.sent")
event.SetSource("http://localhost:8080/")
event.SetData(data)
  • 通过HTTP协议发送这个CloudEvent
t, err := cloudevents.NewHTTPTransport(
    cloudevents.WithTarget("http://localhost:8080/"),
    cloudevents.WithEncoding(cloudevents.HTTPBinaryV02),
)
if err != nil {
    panic("failed to create transport, " + err.Error())
}

c, err := cloudevents.NewClient(t)
if err != nil {
    panic("unable to create cloudevent client: " + err.Error())
}
if err := c.Send(ctx, event); err != nil {
    panic("failed to send cloudevent: " + err.Error())
}

这样我们就通过 Go SDK 方式实现了 CloudEvent 事件的发送和接收。

阿里巴巴云原生关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术圈。”

相关文章
|
2月前
|
算法 数据处理 黑灰产治理
模拟点击问题之设备标签在基础风险能力中起什么作用
模拟点击问题之设备标签在基础风险能力中起什么作用
|
4月前
|
运维 编译器 C#
C# 9.0中的本地函数属性:深化函数级别的控制
【1月更文挑战第17天】C# 9.0引入了本地函数属性的概念,允许开发者在本地函数上应用属性,从而进一步细化对函数行为的控制。这一新特性不仅增强了代码的可读性和可维护性,还为函数级别的编程提供了更多的灵活性。本文将探讨C# 9.0中本地函数属性的用法、优势以及可能的应用场景,帮助读者更好地理解并应用这一新功能。
如何响应BCG的属性列表(CBCGPPropList)改变的事件?
如何响应BCG的属性列表(CBCGPPropList)改变的事件?
|
机器学习/深度学习 算法 数据挖掘
预测分析的定义及作用 | 学习笔记
快速学习预测分析的定义及作用
367 0
预测分析的定义及作用 | 学习笔记
|
人工智能 达摩院 搜索推荐
语音交互如何改变人与互联网的关系 | 学习笔记
快速学习语音交互如何改变人与互联网的关系
120 0
301转向有哪些用途?
除了解决网址规范化问题,还有很多需要做301转向的情形。比如,为保护版权,<a href="https://www.fgba.net/" target="_blank">富贵论坛</a>www.fgba.net拥有不同TLD的多个域名: ▪fgba.cn ▪fgba.cc ▪fgba.co
128 0
|
开发工具
定义无处不在的 Event 事件之 CloudEvents
Event 事件无处不在,然而如果没有一套事件统一的定义标准,那么对于事件处理的开发者来说无疑是痛苦的。CloudEvent 的出现统一了事件的标准,本篇文章简要介绍了这一标准规范协议,以及实际场景中使用的方式。
5306 1
|
API C#
艾伟_转载:把事件当作对象进行传递
  最近在琢磨一些事情,和API设计有关。API设计在很多时候是和语言特性有关的,因此如Java这样的语言,在API设计时会处处受到压抑。而C#就能够出现如Moq或Fluent NHIbernate这样的项目。
865 0