活动可能会因多种原因而被拒。例如,事件接收器服务可能会因中断而暂时不可用;服务在处理事件时可能会遇到错误;或者服务资源可能会耗尽。您可以重试此类暂时性错误。
事件也可能无法传递到事件接收器。例如,事件可能与配置的预期架构不匹配,或者事件的中介可能在事件消息可以路由到其最终目的地之前失败。此类情况会导致持续性错误。
暂时性错误
Eventarc Advanced 可让您处理暂时性错误。这些暂时性错误可以重试,包括具有以下错误代码的错误:
- HTTP
408 Request Timeout
- HTTP
409 Conflict
- HTTP
429 Too Many Requests
- HTTP
500 Internal Server Error
- HTTP
502 Bad Gateway
- HTTP
503 Service Unavailable
- HTTP
504 Gateway Time-out
持久性错误
与暂时性错误不同,持久性错误包括以下情况:
- 当配置的重试次数用尽时发生的错误
- 事件在被路由到目标之前失败时发生的错误
- 导致错误代码被视为不可重试的错误;例如,除暂时性错误所列错误代码之外的错误代码
您可以手动找出持续性错误并妥善处理。
重试暂时性错误
Eventarc Advanced 使用通过指数退避算法确定的延迟时间来处理可重试的错误。默认重试政策从 1 秒延迟开始,每次尝试失败后延迟时间都会加倍(最多 60 秒,最多尝试 5 次)。
您可以使用 Google Cloud 控制台或 gcloud beta eventarc pipelines update
命令更改默认重试政策。
请注意,默认退避系数 2
无法更改。
控制台
在 Google Cloud 控制台中,前往 Eventarc > 流水线页面。
点击流水线的名称。
在流水线详情页面中,点击修改。
在修改流水线页面上的重试政策部分中,修改以下字段:
- 尝试次数上限:重试次数;默认值为
5
次。可以是任何正实数。如果设置为1
,则不会应用任何重试政策,即仅会尝试传送一次消息。 - 延迟时间下限(秒):以秒为单位的初始延迟时间;默认值为
1
秒。必须介于1
和600
之间。 - 延迟时间上限(秒):延迟时间上限(以秒为单位);默认值为
60
秒。必须介于1
和600
之间。
您可以将最小延迟和最大延迟设置为相同的值,以配置线性退避。
- 尝试次数上限:重试次数;默认值为
点击保存。
gcloud
gcloud beta eventarc pipelines update PIPELINE_NAME \
--min-retry-delay=MIN_DELAY \
--max-retry-delay=MAX_DELAY \
--max-retry-attempts=MAX_ATTEMPTS
替换以下内容:
PIPELINE_NAME
:流水线的 ID 或完全限定标识符。MIN_DELAY
:初始延迟时间(以秒为单位);默认值为1
秒。必须介于1
和600
之间。MAX_DELAY
:以秒为单位的最大延迟时间;默认值为60
秒。必须介于1
和600
之间。MAX_ATTEMPTS
:重试次数;默认值为5
次。可以是任何正实数。如果设置为1
,则不会应用任何重试政策,即仅会尝试传送一次消息。
以下示例通过将最小延迟时间和最大延迟时间设置为相同的值来配置线性退避:
gcloud beta eventarc pipelines update my-pipeline \
--min-retry-delay=4 \
--max-retry-delay=4 \
--max-retry-attempts=5
归档消息以处理持续性错误
您可以在收到消息时将其写入 BigQuery 表。这样一来,您就可以手动识别并妥善处理持续性错误。
下文概述了归档活动消息、识别持久性错误以及重试受影响的活动所需的步骤。
- 创建总线。相应地配置总线;例如,发布来自 Google 来源的事件。
- 创建 Pub/Sub 主题。此 Pub/Sub 主题将成为流水线的目标目的地。
- 为 Pub/Sub 主题创建 BigQuery 订阅。BigQuery 订阅是一种导出订阅,可在收到消息时将其写入现有 BigQuery 表。或者,您也可以在创建 BigQuery 订阅时创建表。
创建流水线和注册,以将总线(使用
--cel-match="true"
)收到的每条消息路由到 Pub/Sub 主题。为流水线配置重试政策。例如,以下命令会创建流水线和注册:
gcloud beta eventarc pipelines create my-archive-pipeline \ --destinations=pubsub_topic='my-archive-topic',network_attachment='my-network-attachment' \ --min-retry-delay=1 \ --max-retry-delay=20 \ --max-retry-attempts=6 \ --location=us-central1
gcloud beta eventarc enrollments create my-archive-enrollment \ --cel-match="true" \ --destination-pipeline=my-archive-pipeline \ --message-bus=my-message-bus \ --message-bus-project=my-google-cloud-project \ --location=us-central1
将流水线日志路由到另一个 BigQuery 数据集。
现在,您应该有两个单独的 BigQuery 数据集:一个用于存储 Eventarc 高级总线接收到的每条消息,另一个用于存储流水线日志。
如需识别失败的消息,请使用查询语句联接这两个 BigQuery 数据集中的
message_uid
字段。在确定任何失败的消息后,您可以使用 Eventarc 发布 API 将这些消息再次发布到总线。 例如,您可以部署 Cloud Run 服务或作业,以从 BigQuery 读取消息并直接将其发布到 Eventarc 高级总线。
使事件处理脚本具有幂等性
可重试的事件处理脚本应是幂等脚本,并遵循以下一般准则:
- 许多外部 API 允许您提供幂等键作为参数。如果您在使用此类 API,应将事件来源和 ID 作为幂等键。(提供方必须确保来源 + ID 对于每个不同事件都是唯一的。)
- 此外,您还可以使用 CloudEvents 属性
xgooglemessageuid
来提供幂等性。此属性的值与 Eventarc 高级消息中的message_uid
字段相同。用于唯一标识发布事件的操作。例如,如果同一事件两次发布到总线,则在发送到事件处理脚本时,每个事件将具有不同的xgooglemessageuid
值。 - 幂等性与“至少一次”机制非常契合,因为它能确保重试的安全性。通常情况下,幂等性对于重试来说是不可或缺的。
- 确保代码具有内在的幂等性。例如:
- 确保即使发生多次变更 (mutation),执行结果也不会改变。
- 在事务中,先查询数据库状态再更改状态。
- 确保所有副作用本身也具有幂等性。
- 在服务之外强制执行事务检查(不依赖代码)。 例如,在某个位置留存状态信息,并记录已处理事件的 ID。
- 处理重复的带外调用。例如,设置一个单独的清理进程,在发生重复调用后执行清理。