EventBridge重点特性介绍
以IaC的方式使用EventBridge
摘要:EventBridge 作为构建 EDA 架构的基础设施,提供了灵活丰富的事件收集、处理和路由的能力,并支持通过 OpenAPI、terraform 等方式将这些能力方便快捷的带给用户。本文介绍了 EventBridge 和 IaC 的重点概念和特性,然后演示了如何应用 IaC 理念自动化部署 EventBridge 来使用这些概念和特性。
分享人:王川(弗丁)
视频地址:
一、EDA和EventBridge概述
1.EDA
a.什么是EDA?
EDA 事件驱动架构( Event-Driven Architecture)是一种系统架构模型,它的核心能力在于能够发现系统“事件”或重要的业务时刻(例如交易节点、站点访问等),并实时或接近实时地对相应的事件采取必要行动。这种模式取代了传统的“reguest/response”模型,在这种传统架构中,服务必须等待回复才能进入下一个任务。事件驱动架构的流程是由事件提供运行的。
使用EventBridge可以构建简单或复杂的事件驱动架构,通过标准化的CloudEvents 1.0 协议连接云产品和应用、第三方SaaS等。
EDA具备三个能力:事件收集、事件处理和事件路由。
b.EDA的优势
- 降低耦合
降低事件生产者和订阅者的耦合性。事件生产者只需关注事件的发生,无需关注事件如何处理以及被分发给哪些订阅者。任何一个环节出现故障,不会影响其他业务正常运行。
- 异步执行
事件驱动架构适用于异步场景,即便是需求高峰期,收集各种来源的事件后保留在事件总线中,然后逐步分发传递事件,不会造成系统拥塞或资源过剩的情况。
- 可扩展性
事件驱动架构中路由和过滤能力支持划分服务,便于扩展和路由分发。
- 敏捷性
事件驱动架构支持与各种阿里云产品和应用集成,支持事件路由至任何系统服务,提供各种敏捷高效的部署方案。
2.EventBridge
EventBridge是阿里云提供的一款无服务器事件总线服务。EventBridge 提供的几个核心概念,可以满足构建 EDA 架构的需要。
a.事件源:
- 阿里云官方事件源:用户的云产品所产生的事件;
- 自定义事件源:如第三方SaaS应用,用户自定义数据源;
b.事件总线EventBridge:
- 云服务专用总线:只接收阿里云服务产生的事件;
- 自定义总线:接受自定义事件源产生的事件;
c.事件规则:
EventBridge通过提供简洁的事件模式匹配语法,灵活的事件转换能力实现事件规则:
- 事件模式:用于过滤事件,然后将事件路由到指定的目标;
- 事件目标:包括事件的转换和处理,负责消费事件。
EventBridge增强能力:
EventBridge提供了一些增强能力,使EDA架构中流经的事件更加透明,具备开箱即用的观测和分析能力:
- 事件追踪:可以查看发布到事件总线 EventBridge 的事件内容和处理轨迹;
- 事件分析:对发布到事件总线的各种事件进行查询分析处理和可视化图表展示,以便发现事件内在价值。
- 数值检索:提供基础数值检索能力,支持键入key,value,=,!=,exists,AND,OR等参数,满足事件检索场景的基本诉求。
- 可视化分析:提供GROUP BY,ORDER BY等可视化分析能力,支持多组态,多图表,多维度分析能力。
- 链路追踪:提供事件轨迹能力,还原事件整体链路状态。帮助开发者快速排障,快速定位链路问题。
EventBridge实时事件分析平台截图
二、IaC - Infrastructure as Code
- IaC简介
IaC是一种配置和管理诸如虚拟机、网络等基础设施的实践方法。
在 DevOps 的实践中,IaC 是非常重要的部分,通过将基础设施代码化、版本化,可以轻松的借助版本控制工具来提供诸如single source of truth、协调多人合作的变更、实施严格的 review等,可以借助一些 CI/CD pipeline 工具(甚至 GitOps)来自动触发基础设施资源部署,软件系统的开发者仅付出很小的努力去描述需求,就可以在几分钟后得到所需的虚拟机、网络等云上的资源,极大的缩短了部署时间,同时还能够保证多个环境的配置一致性,降低了因人为操作引起的错误概率。
IaC的代码实践中一般有两种方式:命令式和声明式。
a.命令式
命令式需要明确发出每一个动作的指令,描述的是 How,比如“创建一台 xx 规格的 ECS”。代码需要对每一步动作的顺序仔细编排,处理各种可能的错误,尤其要注意处理好每次变更对已经存在的资源的影响,否则稍有不慎就可能造成服务中断。
举例来说,作为开发者可以通过自己熟悉的编程语言调用阿里云的 OpenAPI 来管理资源,因为这些 API 是类似 Create、Describe、Delete 等操作,这就是一种命令式的 IaC 实践。
b.声明式
声明式需要开发者仅描述自己的需求终态是什么样子,即描述 What,比如“一台 xx 规格的 ECS”。Kubernetes的API就是采用声明式的方式。IaC 工具可以通过描述资源之间的依赖关系自动编排顺序,如果有已经存在的资源,则比对期望的状态和实际状态的差异,并根据差异做出更新;如果不存在,需要进行创建。声明式对开发者非常友好,极大的降低了开发者的心智负担。
- IaC的优势
- 降低成本:有效管理资源,并减少为此投入的人力;
- 提升效率:加快资源交付和软件部署的速度;
- 风险控制:
- 减少错误;
- 提高基础架构一致性;
- 消除配置偏移;
- Terraform
Terraform 作为 IaC 领域的佼佼者,提供了强大的自动化管理基础设施的能力。生态丰富,很多云厂商都提供了官方插件,阿里云的大多数产品(包括 EventBridge)都对 terraform 做了很全面的支持,使得跨多云部署基础设施变得极其简单。
Terraform 提供了自己的语言 HCL(hashicorp configuration language),HCL 具有类似 json 的简洁的语法,通过声明式的资源描述,可以让开发者快速上手。
相关资料:terraform-provider-alicloud目前已经提供了超过163个Resource和113个DataSource,覆盖计算,存储,网络,负载均衡,CDN,容器服务,中间件,访问控制,数据库等超过35款产品,已经满足了大量大客户的自动化上云需求。
三、实践演示
通过两个案例,演示如何利用Terraform基于IaC实践的方式部署EventBridge相关资源。
准备工作:
- 安装 terraform cli 工具,可以参见 https://www.terraform.io/cli 的内容;
- 使用阿里云的provider:创建一个 tf 文件 terraform.tf,内容如下(需要替换<>内的值):
provider "alicloud" {
access_key = "<your access key>"
secret_key = "<your secret key>"
region = "<region id>"
}
【案例1】通过钉钉监控云上资源变化
- 用户需求:用户使用了很多云上的资源作为生产环境,需要感知线上资源的变更操作;
- 解决方案:利用 EventBridge 将来自于阿里云 ActionTrail 的审计事件投递到用户的钉钉。
- 案例目标:
熟悉部署使用EventBridge的default总线;
熟悉EventBridge的事件模式匹配;
熟悉EventBridge的事件转换配置;
详细步骤:
- 首先根据钉钉官方文档创建一个机器人,记下 webhook url 和加签的秘钥;
- 创建一个 tf 文件 1_actiontrail2dingding.tf,内容如下(需要替换<>内的值):
# 声明一个default总线上的规则
resource "alicloud_event_bridge_rule" "audit_notify" {
# default总线默认存在,所以这里可以直接使用
event_bus_name = "default"
rule_name = "audit_notify"
description = "demo"
# 通过filter_parttern即事件的模式匹配(这个案例中是后缀匹配的方式),过滤default总线上所有的ActionTrail事件
# 其他更多模式匹配的介绍可以查阅文档:https://help.aliyun.com/document_detail/181432.html
filter_pattern = jsonencode(
{
"type" : [
{
"suffix" : ":ActionTrail:ApiCall"
}
]
}
)
targets {
target_id = "test-target"
endpoint = "<your dingtalk bot webhook url>"
# type的取值可以查阅文档:https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/event_bridge_rule#type
type = "acs.dingtalk"
# 每个事件目标都有一组对应的param_list,具体可以查阅文档:https://help.aliyun.com/document_detail/185887.html
# 每一个param_list的form关系到事件转换的配置,可以查阅文档:https://help.aliyun.com/document_detail/181429.html
param_list {
resource_key = "URL"
form = "CONSTANT"
value = "<your dingtalk bot webhook url>"
}
param_list {
resource_key = "SecretKey"
form = "CONSTANT"
value = "<your dingtalk bot secret key>"
}
# 这里展示了TEMPLATE类型的事件转换描述
# value是使用jsonpath引用事件内容的字典,template则是模板内容,EventBridge最终会根据这两者结合事件本身渲染出这个参数的值
param_list {
resource_key = "Body"
form = "TEMPLATE"
value = jsonencode(
{
"source": "$.source",
"type": "$.type"
"region": "$.data.acsRegion",
"accountId" : "$.data.userIdentity.accountId",
"eventName" : "$.data.eventName",
}
)
# 这里的msgtype和text都是固定格式,content需要自定义
# content中的$$是Terraform语法的转移
template = jsonencode(
{
"msgtype" : "text",
"text" : {
"content": "来自 $${source} 的 $${type} 审计事件:$${accountId} 在 $${region} 执行了 $${eventName} 操作"
}
}
)
}
}
}
- 在命令行窗口依次执行命令:
- 初始化 terraform init
- 预览变更 terraform plan
- 应用变更 terraform apply
- 在云产品操作台进行操作,以KMS为例,进入在KMS管理控制台,创建凭据:
- 钉钉上收到消息:
- 在EventBright控制台查看事件轨迹,显示投递结构成功。
【案例2】自定义总线触发 FunctionCompute
- 需求:假设一个用户的应用会产生一些事件,其中一个链路是通过 FunctionCompute 对这些事件进行弹性的处理。
- 解决方案:通过 EventBridge 的自定义事件源和函数计算事件目标来实现这个方案。
- 方案目标:
- 熟悉部署使用EventBridge的自定义总线;
- 熟悉“自定义应用”事件源配置;
- 熟悉“FunctionCompute”事件目标配置;
详细步骤:
- 创建一个模拟对事件进行处理的 python 脚本文件 src/index.py,内容如下:
# -*- coding: utf-8 -*-
import logging
def handler(event, context):
logger = logging.getLogger()
logger.info('evt: ' + str(event))
return str(event)
- 创建一个 tf 文件 2_trigger_function.tf,先看文件第一部分:
# 由于用户自己产生的事件需要投递到自定义总线,这里声明一个叫demo_event_bus的自定义总线
resource "alicloud_event_bridge_event_bus" "demo_event_bus" {
event_bus_name = "demo_event_bus"
description = "demo"
}
# 声明一个在demo_event_bus总线上的自定义事件源,用于通过sdk或者控制台向EventBridge投递事件
resource "alicloud_event_bridge_event_source" "demo_event_source" {
event_bus_name = alicloud_event_bridge_event_bus.demo_event_bus.event_bus_name
event_source_name = "demo_event_source"
description = "demo"
linked_external_source = false
}
- 查看效果,执行以下命令:
terraform apply
- 进入事件总线EventBridge页面,看到新创建的demo_event_bus:
- 进入事件源页面,看到新创建的自定义应用demo_event_source:
- 继续看文件 2_trigger_function.tf,第二部分:
# 声明一个叫fc_service的函数计算服务,publish=true意味着会立即部署上传的函数代码。
resource "alicloud_fc_service" "fc_service" {
name = "eb-fc-service"
description = "demo"
publish = true
}
# 将前面准备的python脚本文件打包成zip用于部署到函数计算
data "archive_file" "code" {
type = "zip"
source_file = "${path.module}/src/index.py"
output_path = "${path.module}/code.zip"
}
# 声明一个fc_service服务中的函数,其中filename引用了上面描述的zip包,会将这个代码包上传
resource "alicloud_fc_function" "fc_function" {
service = alicloud_fc_service.fc_service.name
name = "eb-fc-function"
description = "demo"
filename = data.archive_file.code.output_path
memory_size = "128"
runtime = "python3"
handler = "index.handler"
}
- 查看效果,执行以下命令:
terraform apply
- 进入函数计算FC页面,在服务列表中看到新创建的服务eb-fc-service;
- 进入eb-fc-function详情页;
- 继续看文件 2_trigger_function.tf,余下部分:
# 声明一个在demo_event_bus总线上的规则
resource "alicloud_event_bridge_rule" "demo_rule" {
event_bus_name = alicloud_event_bridge_event_bus.demo_event_bus.event_bus_name
rule_name = "demo_rule"
description = "demo"
# 通过匹配source过滤来自于前面创建的自定义事件源的事件
filter_pattern = jsonencode(
{
"source" : ["${alicloud_event_bridge_event_source.demo_event_source.id}"]
}
)
targets {
target_id = "demo-fc-target"
# type的取值可以查阅文档:https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/event_bridge_rule#type
# 需要替换<>内的值
type = "acs.fc.function"
endpoint = "acs:fc:<region id>:<your account id>:services/${alicloud_fc_service.fc_service.name}.LATEST/functions/${alicloud_fc_function.fc_function.name}"
param_list {
resource_key = "serviceName"
form = "CONSTANT"
value = alicloud_fc_service.fc_service.name
}
param_list {
resource_key = "functionName"
form = "CONSTANT"
value = alicloud_fc_function.fc_function.name
}
param_list {
resource_key = "Qualifier"
form = "CONSTANT"
value = "LATEST"
}
# 注意form=ORIGINAL意味着每次投递事件都会将事件的原始内容作为这个参数的值
param_list {
resource_key = "Body"
form = "ORIGINAL"
}
}
}
- 在命令行窗口依次执行命令:
- 初始化 terraform init
- 预览变更 terraform plan
- 应用变更 terraform apply
- 在控制台模拟自定义事件源(demo_event_source)发布事件;
- 在 FunctionCompute 的控制台页面查看函数调用日志;
- 在 EventBridge 控制台查看事件轨迹,目标投递成功。
相关链接
[1] 阿里云 terraform 文档
https://help.aliyun.com/product/95817.html
[2] terraform registry 文档
https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/event_bridge_event_bus
[3] 钉钉官方文档
https://open.dingtalk.com/document/group/custom-robot-access