mcpField
A
amazon-eventbridge-event-bus

amazon-eventbridge-event-bus

github.com/aws云与 DevOps3.3k1.1k 次安装1 天前更新
代码仓库

关于 amazon-eventbridge-event-bus

用于构建和管理新版 Amazon EventBridge 自定义事件总线的技能,涵盖事件发布、订阅筛选与投递、保留和重放,并区分新版 API 与经典 EventBridge。

主要功能

  1. 01创建和配置自定义事件总线
  2. 02发布 JSON 和二进制事件负载
  3. 03筛选并转换订阅事件
  4. 04保留、暂停、恢复和重放事件
  5. 05配置事件源与目标
  6. 06排查投递和授权问题

适用场景

  1. 01设置自定义总线和订阅者
  2. 02选择发布 API 及对应筛选器
  3. 03重放保留事件以进行恢复
  4. 04迁移经典 EventBridge 配置

MCP 相关

建议使用 AWS MCP 服务执行带审计日志的沙箱 CLI 调用;相关指导也适用于标准 AWS CLI。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/aws/agent-toolkit-for-aws --skill amazon-eventbridge-event-bus

安装后在 Claude Code 中输入/amazon-eventbridge-event-bus确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
authorization.md
cloudevents.md
code-samples.md
cost-and-quotas.md
delivery-troubleshooting.md
event-sources.md
filters-and-expressions.md
infrastructure-as-code.md
migrating-from-classic.md
observability.md
provisioning-and-state.md
replay-and-recovery.md
schema-registries.md
security-and-sharing.md
setup-walkthroughs.md
target-configuration.md
target-contract.md

详细介绍

使用新的 EventBridge 自定义事件总线进行构建

概述

新的 EventBridge 自定义事件总线会路由并保留事件。你可以通过两种 API 之一发布事件,订阅者则会筛选事件、按需进行转换,并将每个匹配的事件发送到一个目标。

编写任何筛选器、转换器或目标参数之前,请先阅读第 5 章和第 6 章。 两种发布 API 传递的负载形状不同,为其中一种编写的表达式用于另一种时,会无声地匹配不到任何内容。

发布指标默认开启,因此你始终可以确认事件是否到达总线。订阅者日志默认关闭,因此请在调试投递问题之前开启日志,而不是等到问题发生后再开启(第 18 章)。

最适合搭配 AWS MCP 服务使用,建议通过它在此技能中运行 CLI 调用:它会在经过沙盒隔离的环境中执行调用,并记录审计日志。所有指导也适用于标准 AWS CLI 访问方式。

约定

此技能中的关键词 MUST、MUST NOT、SHOULD 和 MAY 的含义遵循 RFC 2119 中的定义。它们仅出现在决策流程中,因为采取错误的做法会导致配置损坏或事件无声丢失。MUST 表示绝对要求,SHOULD 表示强烈建议,但你可能有具体理由不予遵循,MAY 表示确实可选。

其他内容均为一般说明。描述服务行为的句子不会带有关键词,因为它陈述的是事实,而不是对你的指示。

不适用此技能的情况

此技能仅适用于新的自定义事件总线,也就是通过 eventsv2 CLI 和 eventbridgev2 SDK 客户端访问的服务。它不涵盖:

  • 经典 EventBridge,即包含规则、目标、存档以及 AWS::Events::Rule 上事件模式的 events API。这两项服务共用 events: IAM 命名空间和部分术语,这正是它们容易混淆的原因。如果你正在编写规则,就不是在使用新的总线。如果你正在迁移,第 3 章会介绍这些概念的对应关系。
  • EventBridge Pipes、Scheduler 和 Schemas(经典架构注册表及其发现功能)。它们使用不同的 API。
  • 配置 Firehose 服务本身,例如缓冲提示或记录转换。Firehose 传输流是有效的订阅者目标;第 9 章介绍这方面的内容。

触发示例

  1. “编写一个筛选器,让此订阅者只接收金额超过 $500 的订单。”
  2. “我的生产者显示 PUBLISHED,但队列里什么都没有。我该检查什么?”
  3. “对于 Protobuf 负载,我应该使用 PutEvents 还是 PutRawEvents?”
  4. “设置一个订阅者,重新处理过去两天内的所有内容。”
  5. “编写一个 JSONata 表达式,从事件中提取客户 ID 并写入 DynamoDB 的 putItem。”

防护措施 — 此技能自身文件的位置(MCP 与本地安装)

此技能可以通过两种方式加载,它们会从不同位置解析技能自带的文件。读取参考资料前,请先确定技能的加载方式:

  • 通过 AWS MCP retrieve_skill 工具加载: 此技能未安装在本地文件系统中。你必须使用 retrieve_skill 并通过 file 参数获取每份参考资料(例如 file="references/setup-walkthroughs.md")。请勿在本地使用 file_read 读取这些路径——它们并不存在于磁盘上。
  • 在本地安装(例如 .kiro/skills/amazon-eventbridge-event-bus/ 或 ~/.claude/skills/amazon-eventbridge-event-bus/):使用相对路径从本地技能目录读取文件。

此区别仅适用于技能自身打包的文件。用户数据和会话产物始终从用户的工作目录读取并写入其中。切勿通过 retrieve_skill 获取或写入客户数据。

参考文件

下表所列章节介绍了相关决策和故障模式;详细内容请参阅这些文件。任务符合某一行的描述时,请加载对应文件,默认不要全部加载。

文件何时加载
setup-walkthroughs.md在单个账户中,或通过 AWS RAM 在多个账户间共享,端到端搭建可用的总线,包括前提条件和拆除步骤
code-samples.md编写单个 CLI 或 SDK 调用(Python、Java、TypeScript):创建总线和订阅者、使用任一 API 发布事件、二进制负载、重放、跨账户授权、等待器、单条结果、限流退避
filters-and-expressions.md编写任何过滤模式、JSONata 表达式或读取事件的目标参数;包括两种完整的投递信封
target-configuration.md配置任何订阅者目标,尤其是通用目标
target-contract.md编写实际的 CreateSubscriber 调用:必填字段、每种目标类型的可用示例、字面值与 JSONata、投递错误分类
migrating-from-classic.md从经典版 EventBridge 迁移、规划迁移顺序,或排查导致新总线配置错误的经典用法
event-sources.md使用事件源将 AWS 服务事件或合作伙伴事件发送到总线,或排查转发的事件未到达或未匹配过滤器的问题
provisioning-and-state.md创建或更新总线,或排查资源卡在意外状态的问题
delivery-troubleshooting.md事件已发布但从未到达,或构建能正确统计投递次数的测试装置
authorization.md编写 IAM 策略或总线资源策略、检查跨账户访问,或处理任何将事件转发到总线的操作
replay-and-recovery.md读取历史事件而非新事件、暂停或恢复,或排查看似故障的重放
observability.md设置指标、警报或托管日志投递;读取投递日志;跨账户观测
schema-registries.md发布 Avro、Protobuf 或任何非 JSON 内容;了解接受的内容类型;与 Kafka 并行运行
cloudevents.md发布或使用 CloudEvents,或按 CloudEvents 属性进行过滤
security-and-sharing.md加密总线、跨账户共享或添加标签
cost-and-quotas.md计费机制、跨账户费用分摊、优化事件以降低成本,或处理限流
infrastructure-as-code.md编写 CloudFormation 模板、跨账户拆分堆栈,或设置私有连接

1. 三种资源

事件总线。 你发布事件的对象。它负责路由事件并保留事件。

订阅者。 一个资源,其中声明了你想接收哪些事件以及将它们发送到哪里。它会监视自己的事件总线,保留符合筛选条件的事件,可选择转换每个事件,然后将其发送到唯一一个目标。若要将一个事件发送到多个目标,请在同一事件总线上创建多个订阅者。

事件源。 接入事件总线的托管数据流,可以是 AWS 服务事件,也可以是合作伙伴/SaaS 来源。

名称和标识符:

  • 事件总线 ARN 和订阅者 ARN 都会在名称后附加由服务生成的 ID: arn:aws:events:us-east-1:111122223333:event-busv2/my-bus/exampleid0123456789abcdef。 请保存完整 ARN,而不是名称,因为名称本身无法唯一标识资源;删除事件总线后,以相同名称重新创建会得到不同的 ID。
  • 事件源名称在账户内唯一,而非在事件总线内唯一。
  • 有三个名称用于标识此服务,且彼此不同。 CLI 命令和端点主机名为 eventsv2,例如 aws eventsv2 create-event-bus 和 eventsv2.{region}.amazonaws.com。SDK 客户端为 eventbridgev2。IAM 操作和 ARN 使用与经典 EventBridge 共用的 events,例如 events:PutEvents 和 arn:aws:events:...:event-busv2/...。请参阅第 14 章。

2. 带有持久日志的路由器

事件总线会将每个事件路由给匹配的订阅者,同时还会在配置的时长内保留事件;此时长按事件总线设置,通过 StorageConfiguration.RetentionPeriodInDays 指定(1 到 365 天)。正是保留机制让其他四项功能成为可能:起始位置、暂停和恢复、重放,以及让今天创建的订阅者读取昨天发布的事件。保留窗口的起点会限制在事件总线创建时间,因此对于较新的事件总线,即使是近期的过去时间戳也可能超出窗口。

3. 从经典 EventBridge 迁移

经典规则及其目标在新事件总线上对应一个订阅者。新事件总线有四个经典版本中没有对应概念的功能:事件总线自身的保留机制、订阅者起始位置、暂停和恢复并保留待处理事件,以及采用不同负载模型的两种发布 API。最后一点会影响筛选条件的编写方式,因此原样移植的经典事件模式仅适用于 PutEvents。概念映射、可能不再适用的习惯以及分步迁移流程,请参阅 migrating-from-classic.md。

4. AWS 服务和合作伙伴事件源

事件源是一个托管式事件流,会将事件送入你的总线。你需要创建事件源,指定目标总线和一个来源,服务便会在经典 EventBridge 侧为你建立转发。无需角色,也无需投递代码:托管路径使用服务自身的身份。

Configuration 是一个带判别字段的结构,MUST 设置且只能设置一个变体:

变体来源必填成员
AwsServiceEventsConfiguration一个 AWS 服务,例如 aws.s3AwsService
PartnerEventsConfiguration一个经典合作伙伴事件源PartnerEventSourceArn

两者都可以设置可选的 Pattern,用于缩小转发范围;该模式会在经典侧根据经典信封进行评估。你的模式 MUST NOT 包含 source 键,也 MUST NOT 在顶层包含 account 或 region,因为服务会自行设置这些字段,以便将转发限定到你的账户和来源。

转发的事件会以完整的经典信封到达。Data 中保存该信封,ContentType 为 application/eventbridge+json,你的内容位于 $events.Data.detail,而来源和 detail-type 位于 SystemMetadata 中,分别为 aws:Source 和 aws:DetailType。因此,经典规则的 source 筛选条件不会直接适用:等效做法是使用 SYSTEM_METADATA 筛选条件 {"aws:Source":["aws.s3"]}。

**只有这一对 SystemMetadata 字段能证明事件由 AWS 服务或合作伙伴生成。**任何发布调用都无法写入这两个键。原始负载可以完全仿造该信封,因此,对负载中 source 字段使用 DATA 筛选条件时,伪造事件和真实事件都会匹配。在来源可信度很重要时,你 SHOULD 筛选 aws:Source,并且 MUST 匹配其值,而不只是判断它是否存在,因为直接调用 PutEvents 也会设置该键,值取自其自身的 Source,且该值永远不会带有 aws. 前缀。

EventBusArn 不可变。恢复方式取决于失败类型:如果状态为 CREATE_FAILED 或 UPDATE_FAILED,UpdateEventSource 会使经典侧恢复为与你的记录一致;如果状态为 DELETE_FAILED,唯一的恢复方式是再次执行删除操作。

总线所有者在创建时拥有控制权。CreateEventSource 会根据目标总线上的 events:source 条件键进行授权;对于已存在的事件流,所有者可使用 RevokeResource 停止它(第 22 章)。前置条件、加密、死信处理,以及经典账户中会显示的内容,请参阅 event-sources.md。

5. 选择发布 API

此选择决定载荷形状,而载荷形状又决定了你接下来要编写的每个筛选器、转换器和目标参数。

PutEventsPutRawEvents
载荷字段Detail,一个 JSON 字符串Data,一个 base64 数据块
载荷必须为 JSON是否,任何格式均可
每个条目的必填项Source、DetailTypeData、SystemMetadata
ContentType不接受;服务会写入 application/eventbridge+json必填,位于每个条目的 SystemMetadata 中
经典样式字段可使用 Resources、Time不存在
自定义元数据否Metadata,最多 100 个键
排序和去重输入SystemMetadata.EventGroupId、SystemMetadata.DeduplicationId同样是这两个字段

对于需要经典样式封装的 JSON 事件,请使用 PutEvents。对于二进制或非 JSON 载荷、自定义元数据键,或需要载荷按原样传递的情况,请使用 PutRawEvents。

两者都会按请求条目的顺序返回对应的结果条目,因此可按索引进行关联。每个结果条目都包含 SuccessCode,或 ErrorCode 和 ErrorMessage。SuccessCode 的值为 PUBLISHED 或 DEDUPLICATED,而且 DEDUPLICATED 表示成功,不是错误。 如果代码将每次成功都视为新事件,就会误以为去重导致了投递问题。

发布 Avro 或 Protobuf 时,必须在每个发布请求中指定架构注册表,而不是在总线上指定;如果将注册表配置在错误的位置,事件就无法解码。application/octet-stream 无需注册表,因为服务根本不会解码这些字节(schema-registries.md)。

6. 寻址:每个字段的位置

筛选器、转换器和目标参数共用一种寻址模型,而且 两种发布 API 的寻址方式并不相同。 每个事件都会通过三个顶层名称进行投递:Data(载荷)、Metadata(你的自定义键,仅限 PutRawEvents)和 SystemMetadata(服务分配的字段及排序字段)。通过原始方式发布的载荷直接位于 Data 中;PutEvents 载荷则位于经典封装内,在 detail 下多嵌套一层。因此,同一字段对于一种 API 的路径是 $events.Data.m,对于另一种则是 $events.Data.detail.m;使用错误的形式不会报错:它只会解析为空,筛选器也不会匹配,转换器则不会输出任何内容。如果通过这两种 API 向同一总线发布事件,请编写同时适用于两者的表达式,或为每种流量类型设置各自的订阅者;不存在适用于两者的通用寻址形式。两个封装的完整内容及所有 SystemMetadata 字段,请参阅 filters-and-expressions.md。

7. 筛选

订阅者的 FilterConfiguration 包含一个 Filters 列表,事件必须匹配列表中的每个筛选器才能投递:筛选器之间是 AND 关系,而不是 OR 关系。每个筛选器都有一个 Pattern 和一个 Scope(DATA、METADATA 或 SYSTEM_METADATA),每个范围只能有一个筛选器。DATA 模式根据第 6 章所述的形状编写,因此一个模式无法同时适用于两种发布 API;每个模式只对其中一种 API 有效,对另一种 API 则会静默地匹配不到任何内容。创建时 FilterConfiguration 是可选的;未配置该项的订阅者会接收总线上的每个事件。无法匹配任何内容的筛选器与故障订阅者无法区分,因此请通过观察目标,确认一个应当匹配的情况和一个不应匹配的情况。

8. 转换

订阅者的 Transformer 有三种类型:RAW(默认)仅传递负载,WITH_METADATA 传递三段式封套,JSONATA 传递表达式的结果。JSONata 表达式以 {% %} 分隔符包裹,并将事件作为 $events 来访问,访问方式与第 6 章完全相同。大多数标量目标参数也接受相同格式的表达式。有些成员不接受表达式,必须使用字面值:API Gateway 标头名称、消息属性的 BinaryValue 和 InvocationType。表达式只会在创建时进行语法检查,因此其结果要到传递时才能确定。若 JSONATA 转换器的表达式抛出错误或求值结果为空,就会导致客户责任的传递失败,因此应当进行测试。

9. 目标及其参数块

InvokeConfiguration 包含 TargetArn、RoleArn,以及最多一个与目标匹配的参数块。通用目标必须携带其参数块;任何类型化参数块都可以省略。经典事件总线和 Firehose 传输流都是无需参数块的有效目标。

服务会根据 ARN 解析目标类型,并在存储任何内容之前检查其负责的约束:参数块是否与目标匹配、ARN 的区域、分区和账户是否属于该服务,以及每个表达式是否都能解析。它不会复刻目标 API 自身的参数语法、取值范围、标识符限制或该 API 要求的成员——这些仍由目标负责,因此,目标会拒绝的请求在创建时仍会被接受,并在传递时失败。

  1. 你必须提供通用目标所要求的参数块。 类型化参数块可以省略:KinesisParameters: {} 会被存储,Kinesis 在被调用时会报告缺少 PartitionKey。
  2. 你不得在每条消息的字段中放入常量,因为固定的去重 ID 会导致目标丢弃第一条消息之后的所有消息。两种形式都不会针对目标的取值范围、必填要求或 FIFO 适用性进行检查,因此,值错误或缺失都会导致传递失败。
  3. 你应当检查目标服务自身的规则。 目标会在传递时检查其是否存在、是否可访问、是否已授权、封套后的大小,以及其 API 所需的字段。
  4. 你应当在目标端确认,因为 PUBLISHED 响应并不代表已传递,批处理 API 返回的 HTTP 200 也不代表已传递,因为其中可能包含单独失败的条目。
  5. 测试前,你必须附加死信队列并启用日志,还必须向传递角色授予该队列上的 sqs:SendMessage 权限,否则失败不会留下任何信号。

每条规则的失败模式、确切的拒绝消息和各目标的参数块,详见 target-configuration.md。在编写调用本身之前,请先加载 target-contract.md,查看必填字段列表、每种目标类型的一个可用示例,以及传递错误分类。

10. 通用目标

通用目标可直接调用任何受支持的 AWS API,无需中间函数。目标 ARN 具有固定格式:

arn:{partition}:events:::aws-sdk:{service}:{apiAction}

有四点需要正确设置,每一点设置错误都会在创建时失败,并显示说明问题的消息: apiAction 使用驼峰命名法,首字母小写(putItem);service 是 SDK 服务 ID,并不总是显而易见的单词(Step Functions 的值是 sfn);UniversalTargetParameters.Input 为必填项,保存 API 请求的 JSON 或可生成该请求的 JSONata 表达式;BatchConfiguration 为必填项。服务的验证文本会将通用目标简称为“USI target”;两者含义相同。

11. 排序与去重

排序是订阅者的属性。Type 为 UNORDERED(不保证顺序)或 FIFO(在事件组内有序),发布时会按 SystemMetadata.EventGroupId 对事件分组。FIFO 目标会对组 ID 强制执行自身的长度和字符限制;无法投递的事件会阻塞其所属组中的后续事件,而同一订阅者上的其他组仍可继续处理,因此组 ID 应保持简短,不要根据无界输入生成组 ID。

去重在发布时进行,有两种方式。请求中的 DeduplicationConfiguration.DeduplicationType: CONTENT_BASED 会对事件内容进行哈希,而 CONTENT_BASED 是唯一的 DeduplicationType 值。如果要根据自己的键去重,请省略 DeduplicationConfiguration,并在每个条目的 SystemMetadata.DeduplicationId 中设置该键。无论采用哪种方式,被抑制的重复事件都会返回 SuccessCode: DEDUPLICATED。

请将这两个概念区分开。总线级去重决定是否接受事件。FIFO 目标自身的去重 ID(在目标参数块中设置)决定该目标是否接受投递。这是不同层级中的不同字段,而且第二个是每条消息各自的值(第 9 章,规则 2)。

12. 重试与死信

RetryPolicy 有三个成员:

成员范围默认值
MaxRetryAttempts0-1855
MaxEventAgeInSeconds60-86400300
RetryStrategyALLALL

投递会在先达到的限制处停止,失败的投递会一直重试到那时。因此,只有在 MaxEventAgeInSeconds 窗口结束后,才能确定“没有收到任何内容”。

OnFailureConfiguration.Arn 指定用于死信处理的 SQS 队列,SQS 是唯一受支持的目标。事件源不接受 FIFO 队列,并且会返回唯一的消息 OnFailureConfiguration.Arn must name a standard SQS queue: FIFO queues are not supported as EventSource dead-letter queues; 订阅者则接受 FIFO 队列,因此这两种资源在这一点上有所不同。还需规划应对另外两个限制:死信记录通过 ID 和时间戳标识失败的事件,不包含负载,因此重放需要事件仍处于保留期内;并且投递角色必须能够写入死信队列,否则失败事件无处可去,会悄无声息地消失。

13. 投递权限

InvokeConfiguration.RoleArn 是服务用来调用目标的角色。该角色必须属于调用账户,其信任策略必须允许 events.amazonaws.com 服务主体,并且该策略应当通过 aws:SourceAccount 和 aws:SourceArn 设置条件。该角色必须具有目标所需的操作(sqs:SendMessage、sns:Publish、lambda:InvokeFunction、kinesis:PutRecords、states:StartExecution,或通用目标所需的其他操作),并且对死信队列具有**sqs:SendMessage 权限**,否则投递会失败,不会写入失败记录,也无法观察到任何情况。

CreateSubscriber 还会检查该角色的 iam:PassRole 权限,因此无法传递的角色会在目标验证运行前返回 AccessDeniedException。上述列表还遗漏了四项:Kinesis 投递调用 PutRecords,Firehose 调用 PutRecordBatch,API Gateway 需要 execute-api:Invoke,API destination 需要 events:InvokeApiDestination。

创建时会检查目标 ARN 的格式、类型、区域、分区和账户,但不会检查其是否存在或是否可访问:格式正确但未指向任何资源的 ARN 也会被存储,并在投递时失败。

14. 授权:调用方需要什么

第 13 章介绍 EventBridge 用于调用目标的角色。本章介绍调用方需要什么才能访问 API。

每个操作名称都以 events: 开头。 CLI 命令和端点主机名是 eventsv2,SDK 客户端的名称是 eventbridgev2,但 IAM 命名空间是 events,与经典 EventBridge 共用。你绝不能在 IAM 策略中写入 eventbridgev2: 或 eventsv2:,因为这两个名称都不是有效操作,而且都会默认拒绝:策略虽然能通过验证,但不会授予任何权限。从刚运行的命令生成策略并授予 eventsv2:PutEvents,就是这种情况的常见原因。逐项名称对照表见 authorization.md。

发布按条目针对事件总线 ARN 授权,不支持部分授权:如果任一条目未通过条件检查,整个请求都会被拒绝,因此一个批次的授权范围取决于其中授权最少的条目。

创建订阅方或事件源时,授权针对的是事件总线,因此事件总线是跨账户授权点:事件总线所有者在此决定其他账户是否可以附加任何内容。

使用你提供的角色将事件转发到事件总线时,授权在接收事件时按事件进行:真实的 AWS 或合作伙伴事件需要 events:PutEvents,你自行生成的任何事件都需要 events:PutRawEvents。因此,转发器同时处理这两类事件时,必须授予这两个操作,否则只授予其中一个会导致一半事件流被静默拒绝。条件键、创建时的逐项检查以及撤销语义见 authorization.md。

15. 预置与资源状态

创建事件总线是异步操作:CreateEventBus 返回时状态为 State: CREATING,之后事件总线才会变为可用。请使用 waiter,而不要手动编写轮询逻辑,因为遇到失败状态时 waiter 会快速失败,并显示 StateReason,而不是一直轮询到超时:

aws eventsv2 wait event-bus-active  --event-bus-arn "$BUS_ARN"

事件总线有七种状态,值得注意的不对称之处在于两种失败状态:UPDATE_FAILED 可以原地恢复,而 CREATE_FAILED 不可以。 创建失败后只能删除,因此必须删除该事件总线并重新创建。删除事件总线前,请先删除订阅方和事件源;如果事件总线仍有任一对象,调用 DeleteEventBus 会返回 ResourceInUseException,并在消息中指出阻止删除的对象类型。已撤销的订阅方和事件源不会阻止删除。

创建操作通过 ClientToken 实现幂等。 CreateEventBus、CreateSubscriber 和 CreateEventSource 都接受一个令牌,重试时携带相同令牌会返回原始结果,而不是创建第二个资源。如果省略该字段,SDK 会在每次调用时生成新的令牌,因此你自己的代码发起重试时会构造新请求、获取新令牌并创建第二个资源。因此,只要重试可能跨越进程、队列或工作流步骤,你就必须提供自己的 ClientToken。 不匹配错误和名称冲突详见 provisioning-and-state.md。

16. 安全更新

每个更新 API 都遵循一条规则;如果理解有误,就会静默丢弃你无意更改的配置:

省略顶层成员表示保持不变。提供配置块则会替换整个配置块。

因此,为了更改其中一个字段而在更新请求中提供 Configuration、FilterConfiguration 或 LogConfiguration,会清除该配置块中的所有其他字段。 更新事件源时如果省略 Pattern,返回的事件源就完全没有模式,过滤器会扩大到匹配所有内容,而且不会发出警告。因此,你必须读取资源,修改整个配置块,将整个配置块写回,然后再次读取资源,因为再次读取是确认已存储内容的唯一方式。

17. 暂停、恢复和重放

没有单独的重放 API。重放是订阅者的起始位置,会根据总线保留的事件进行评估,因此仍在保留期内的内容都可以重新读取。

  • 创建时的 StartingPosition 可以是 LATEST(仅接收订阅者创建后发布的事件),也可以是 POINT_IN_TIME(从保留历史中的某个时间点开始)。
  • 暂停是通过 UpdateSubscriber 将 State 设为 STOPPED。积压事件会不断累积,但受保留期限制;恢复时是传递还是跳过积压事件,由 ResumePosition 决定。
  • 重放的事件会带有标记。 SystemMetadata."aws:DeliveryType" 的值为 REPLAY,而不是 LIVE,因此使用方可以确保重放具有幂等性。
  • 重放启动时会有延迟,之后会以实时速度运行,因此在判定重放是否失效之前,请考虑这段延迟。

18. 可观测性:指标和日志

两个方面可以告诉你服务正在做什么,但它们的默认设置恰好相反。

发布指标默认启用,位于 AWS/EventsV2 命名空间中,维度为 {EventBus},以及用于归因到事件源的流量的 {EventBus, EventSource} 和用于入口字节数的 {EventBus, PublisherAccount}。将 PublishEventsApproximateCallCount 与 PublishEventsApproximateSuccessCallCount 对比,是确认生产者是否已向总线发送请求的最简单方法。结果指标统计的是调用次数,而不是事件数,因此只要调用返回了响应,即使其中的所有条目都被拒绝,也会计为成功;要判断事件是否成功送达,应查看 PublishEventsEntryCount 和 PublishEventsFailedEntriesCount。EventBus 维度的值不是总线 ARN;使用 ARN 查询不会返回数据,看起来就像没有流量一样。

订阅者日志默认关闭,要让日志生效,需要满足两个条件:将 LogConfiguration.Level 调高至 OFF 以上,并配置 CloudWatch Logs 交付日志,将订阅者连接到日志组。请在调试交付问题之前完成这两项设置,而不是之后。交付设置、指标列表和 EVENT_DELIVERY_ATTEMPT 记录字段见 observability.md。

19. 验证交付

发布响应表示服务已接受事件,但并不能说明事件是否已交付。要确认事件是否到达,请查看目标端。

健康的交付会很快到达目标,因此尚未及时到达的事件很可能是交付失败,而不是仍在传输中。 但只有在重试窗口结束后,才能据此断定“没有事件到达”,因为在此之前,交付失败的事件仍会继续重试。

两种计数错误会让正常工作的配置看起来像是出了问题。从 SQS 队列读取消息却不删除,会导致消息被重复读取,因此原始计数会高估交付次数。此外,共享目标会累积先前运行产生的消息,因此每次实验都应使用全新的目标,或使用本次运行独有的标记。

20. 已发布但始终未到达

几乎所有交付问题的表现都一样:发布成功,但目标为空。你 SHOULD 按顺序执行 delivery-troubleshooting.md 中的步骤;其中列出了 11 种原因,并按最常见的原因优先排序。

无需打开文件即可尝试的三个快捷方法:

  • 你 SHOULD 首先检查 PublishEventsEntryCount(第 18 章)。如果值为 0,问题就出在总线上游,此时下游的任何情况都无关紧要。
  • 你 SHOULD 开启订阅者日志。 设置 INFO 和 IncludePayload: FULL,即可查看每次尝试的错误和发送的确切 target_input,无需等待重试耗尽。
  • 若要查看服务所看到的事件内容,你 MAY 添加第二个订阅者,设置 Transformer: { Type: WITH_METADATA } 且不设置筛选条件,并将其指向你拥有的队列。

21. 错误和客户端重试

批次响应按条目返回。 发布请求可能在请求级别成功,但部分条目失败,因此请检查 FailedEntryCount 和每个条目,而不只是 HTTP 状态码。

某些格式错误的输入会导致整个请求失败,而非仅一个条目失败。 反序列化请求时捕获到的任何错误都会拒绝整个批次,并连带拒绝其中有效的条目。请在客户端按条目验证,并将批次保持在足够小的规模,以便丢失一个批次时损失不大。

可重试的错误。 ConcurrentModificationException 和 ThrottlingException 可通过退避重试。InvalidInputException、AccessDeniedException、ResourceNotFoundException 和 IdempotentParameterMismatchException 不可重试;请修正请求。

持续出现 500 错误时,首先应检查客户端的线缆类型问题。 常见原因是发送了错误 JSON 类型的值,例如预期为字符串却传入数字,或预期为纪元秒数却传入 ISO-8601 字符串。根据约定,SDK 会重试 500 错误,但重试无法修复格式错误的请求,因此升级处理前请先检查类型。

22. 安全、加密、共享和标记

  • 加密通过总线上的 EncryptionConfiguration.KmsKeyIdentifier 配置。调用方在创建时需要对密钥拥有 kms:DescribeKey 权限;对于 CMK 总线,每个发布者也都需要对该密钥拥有 kms:Decrypt 权限,因为无法读取总线事件的调用方不允许写入事件。如果服务端的密钥策略不可用,总线会进入 CREATE_FAILED 状态,并显示 StateReason: KMS_ACCESS_DENIED(参见 security-and-sharing.md)。
  • 要与其他账户共享总线,请使用 AWS RAM。 资源策略可用于处理 RAM 无法表达的权限,但手写策略在 RAM 中不可见,因此需要由你负责跟踪。
  • 某些操作仅限总线所有者执行,包括撤销共享资源,因此仅授予权限并不总是足够。撤销是终止性的,且仅适用于指定的单个资源;因此,如果要停止某个账户,而不是某个资源,还需在总线资源策略中拒绝该账户的 events:CreateSubscriber 和 events:CreateEventSource 权限(参见 authorization.md)。

23. 成本、配额和平台集成

有四项因素会影响设计决策。当前价格和配额值请参阅 EventBridge 定价页面和 Service Quotas,而非本文档。

  • 接收和传送都会按 KB 向上取整计费,因此,许多小事件的费用会高于按字节总量估算的费用;将相关事实批量放入一个事件更省钱。
  • “增强操作”会单独计费:JSONata 求值、架构反序列化和 CONTENT_BASED 去重。如果已有幂等键,优先使用每个条目的 DeduplicationId,且不设置 DeduplicationConfiguration。
  • 两个发布 API 的节流额度按账户合并计算,因此在两者间分流流量的服务共用一个额度。订阅方管理有独立的账户级限额,因此发布尚有余量时,CreateSubscriber 和 DeleteSubscriber 仍可能受到节流。遇到 ThrottlingException 时请使用退避策略(第 21 章)。
  • CloudFormation 通过 AWS::EventsV2:: 支持新总线,包含三种类型。六个订阅方属性仅可在创建时设置,替换时会先删除再创建,因此更改模板中的目标 ARN 可能会导致间隙期间发布的事件悄然丢失。

评论

支持 Markdown