重试事件

事件可能会因多种原因而被拒绝。例如,事件接收器服务可能会因服务中断而暂时不可用;服务在处理事件时可能会遇到错误;或者服务资源可能会耗尽。此类 暂时性错误可以重试。

事件也可能无法传送给事件接收器。例如,事件可能与配置的预期架构不匹配,或者事件的调解可能会在事件消息路由到最终目的地之前失败。此类情况会导致 永久性错误

暂时性错误

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 无法更改。

控制台

  1. 在 Google Cloud 控制台中,前往 Eventarc > 流水线 页面。

    打开“流水线”

  2. 点击流水线的名称。

  3. 流水线详情 页面中,点击修改

  4. 修改流水线 页面中的重试政策 部分,修改以下字段:

    • 尝试次数上限:传送尝试次数;默认值为 5 次尝试。可以是任意正整数。如果设置为 1,则不会应用任何重试政策,即仅会尝试传送一次消息。
    • 延迟时间下限(秒):初始延迟时间(以秒为单位);默认值为 1 秒。必须介于 1600 之间。
    • 延迟时间上限(秒):延迟时间上限(以秒为单位);默认值为 60 秒。必须介于 1600 之间。

    您可以将延迟时间下限和上限设置为相同的值,以配置线性退避。

  5. 点击保存

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 秒。必须介于 1600 之间。
  • MAX_DELAY:延迟时间上限(以秒为单位);默认值为 60 秒。必须介于 1600 之间。
  • MAX_ATTEMPTS:传送尝试次数;默认值为 5 次尝试。可以是任意正整数。如果设置为 1,则不会应用任何重试政策,即仅会尝试传送一次消息。

以下示例将延迟时间下限和上限设置为相同的值,以配置线性退避:

gcloud eventarc pipelines update my-pipeline \
    --min-retry-delay=4 \
    --max-retry-delay=4 \
    --max-retry-attempts=5

归档消息以处理永久性错误

您可以在收到消息时将其写入 BigQuery 表。这样,您就可以手动识别永久性错误并妥善处理。

下面简要介绍了归档事件消息、识别永久性错误以及重试受影响的事件所需的步骤。

  1. 创建总线。正确配置 总线;例如, 发布来自 Google 来源的事件
  2. 创建 Pub/Sub 主题。此 Pub/Sub 主题将成为流水线的目标目的地。
  3. 为 Pub/Sub 主题创建 BigQuery 订阅 。BigQuery 订阅是一种可在收到消息时将其写入现有 BigQuery 表的导出订阅。或者,您也可以在创建 BigQuery 订阅时创建表。
  4. 创建一个流水线和注册 用于将总线收到的每条消息(使用 --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-central1
    
    gcloud 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
    
  5. 将流水线日志路由到 另一个 BigQuery 数据集。

    现在,您应该有两个单独的 BigQuery 数据集:一个用于存储 Eventarc Advanced 总线收到的每条消息,另一个用于存储流水线日志。

  6. 如需识别失败的消息,请使用 查询语句将 两个 BigQuery 数据集联接到 message_uid 字段。

  7. 识别任何失败的消息后,您可以将其重新发布到总线 使用 Eventarc Publishing API。 例如,您可以 部署 Cloud Run 服务或作业 以从 BigQuery 读取消息并 将其直接发布 到 Eventarc Advanced 总线。

使事件处理程序具有幂等性

可重试的事件处理程序应具有幂等性,并遵循以下一般准则:

  • 许多外部 API 允许提供幂等键作为参数。如果您在使用此类 API,应将事件来源和 ID 作为幂等键。(生产者必须确保 来源 + ID对于每个不同事件都是 唯一的。)
  • 此外,您还可以使用 CloudEvents 属性 xgooglemessageuid 来提供幂等性。此属性的值与 Eventarc Advanced 消息中的 message_uid 字段相同。它可唯一标识发布事件的操作。例如,如果同一事件两次发布到总线,则每个事件在发送到事件处理脚本时都将具有不同的 xgooglemessageuid 值。
  • 幂等性与“至少一次”机制非常契合,因为它能确保重试的安全性。通常情况下,幂等性对于重试来说是不可或缺的。
  • 确保代码具有内在的幂等性。例如:
    • 确保即使发生多次变更 (mutation),执行结果也不会改变。
    • 在事务中,先查询数据库状态再更改状态。
    • 确保所有副作用本身也具有幂等性。
  • 在服务之外强制执行事务检查(不依赖代码)。 例如,在某个位置留存状态信息,并记录已处理事件的 ID。
  • 处理重复的带外调用。例如,设置一个单独的清理进程,在发生重复调用后执行清理。

后续步骤