事件可能会因多种原因而被拒绝。例如,事件接收器服务可能会因服务中断而暂时不可用;服务在处理事件时可能会遇到错误;或者服务资源可能会耗尽。此类 暂时性错误可以重试。
事件也可能无法传送给事件接收器。例如,事件可能与配置的预期架构不匹配,或者事件的调解可能会在事件消息路由到最终目的地之前失败。此类情况会导致 永久性错误。
暂时性错误
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 eventarc pipelines update
命令更改默认重试政策。
请注意,默认退避系数 2 无法更改。
控制台
在 Google Cloud 控制台中,前往 Eventarc > 流水线 页面。
点击流水线的名称。
在流水线详情 页面中,点击修改 。
在修改流水线 页面中的重试政策 部分,修改以下字段:
- 尝试次数上限:传送尝试次数;默认值为
5次尝试。可以是任意正整数。如果设置为1,则不会应用任何重试政策,即仅会尝试传送一次消息。 - 延迟时间下限(秒):初始延迟时间(以秒为单位);默认值为
1秒。必须介于1到600之间。 - 延迟时间上限(秒):延迟时间上限(以秒为单位);默认值为
60秒。必须介于1到600之间。
您可以将延迟时间下限和上限设置为相同的值,以配置线性退避。
- 尝试次数上限:传送尝试次数;默认值为
点击保存 。
gcloud
gcloud 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 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 eventarc pipelines create my-archive-pipeline \ --destinations=pubsub_topic='my-archive-topic' \ --min-retry-delay=1 \ --max-retry-delay=20 \ --max-retry-attempts=6 \ --location=us-central1gcloud 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 Advanced 总线收到的每条消息,另一个用于存储流水线日志。
如需识别失败的消息,请使用 查询语句将 两个 BigQuery 数据集联接到
message_uid字段。识别任何失败的消息后,您可以将其重新发布到总线 使用 Eventarc Publishing API。 例如,您可以 部署 Cloud Run 服务或作业 以从 BigQuery 读取消息并 将其直接发布 到 Eventarc Advanced 总线。
使事件处理程序具有幂等性
可重试的事件处理程序应具有幂等性,并遵循以下一般准则:
- 许多外部 API 允许提供幂等键作为参数。如果您在使用此类 API,应将事件来源和 ID 作为幂等键。(生产者必须确保 来源 + ID对于每个不同事件都是 唯一的。)
- 此外,您还可以使用 CloudEvents 属性
xgooglemessageuid来提供幂等性。此属性的值与 Eventarc Advanced 消息中的message_uid字段相同。它可唯一标识发布事件的操作。例如,如果同一事件两次发布到总线,则每个事件在发送到事件处理脚本时都将具有不同的xgooglemessageuid值。 - 幂等性与“至少一次”机制非常契合,因为它能确保重试的安全性。通常情况下,幂等性对于重试来说是不可或缺的。
- 确保代码具有内在的幂等性。例如:
- 确保即使发生多次变更 (mutation),执行结果也不会改变。
- 在事务中,先查询数据库状态再更改状态。
- 确保所有副作用本身也具有幂等性。
- 在服务之外强制执行事务检查(不依赖代码)。 例如,在某个位置留存状态信息,并记录已处理事件的 ID。
- 处理重复的带外调用。例如,设置一个单独的清理进程,在发生重复调用后执行清理。