如何使用 Azure EventGrid webhook 保持幂等性?

How do you maintain idempotency with Azure EventGrid webhooks?

我已经配置了一个 EventGrid 订阅,以便在创建资源时启动对资源组中事件的 Web 挂钩调用。

网络钩子调用处理成功,我return一个200 OK。为了保持幂等性,我将所有发生在 webhook_events table 中的事件与事件的 id 一起存储。任何新事件都会通过 id.

检查它们是否存在于 table 中

Azure EventGrid 在 return 返回 200 OK 后尝试从重试队列中删除事件。无论我响应 200 OK 的速度有多快,EventGrid 都会可靠地重试发送。

我多次收到同一个事件(正如我所说,Eve​​ntGrid 总是重试,因为它无法足够快地从重试队列中删除事件)。然而,这不是我问题的重点;相反,问题存在于这样一个事实,即这些重试中的每一次都为我提供了不同的 id 事件。这意味着我无法从逻辑上确定事件的唯一性,并且我的应用程序代码未以幂等方式执行。

尽管事件重试之间没有唯一标识符,但如何保持我的应用程序和 Azure 之间的幂等性?

如果您查看 documentation

,这就是 EventGrid 的实现方式

If the endpoint responds within 3 minutes, Event Grid will attempt to remove the event from the retry queue on a best effort basis but duplicates may still be received.

您可以使用后端代码清理日志和存储的数据,使用事件和消息 ID 识别重复项。

id field 实际上每个事件都是唯一的,并且在重试之间保持相同,因此可用于重复数据删除。

您 运行 遇到的是 Azure 资源管理器 (ARM) 生成的某些事件的特定问题。具体来说,您看到的这两个事件实际上是不同的事件,而不是重复事件,由 ARM 在某些资源类型的创意流程的不同阶段生成。

ARM 充当各种 Azure 服务的 API 前门,并发出 a set of events 因为这些服务是通用的,通常要了解发生的事情的详细信息,您需要查看数据有效载荷。例如,ARM 将为它从 Azure 服务接收到的每个 2xx 状态代码发出一个成功事件,因此接受 202 和创建 201 可能会导致发出两个事件,并且查看差异的唯一方法是在数据负载中.

这是一个已知的痛点,我们正在努力发出更多高保真事件,这些事件将在这些场景中更清晰、更容易做出反应。理想状态将是 Azure 控制平面的各种变更源。