gpt4 book ai didi

python-3.x - 处理 webhook 时的并发问题

转载 作者:行者123 更新时间:2023-12-05 02:47:33 24 4
gpt4 key购买 nike

我们的应用程序基于外部服务的网络 Hook 创建/更新数据库条目。 webhook 发送对象的外部 id,以便我们可以获取更多数据进行处理。为获取更多数据而进行往返处理的 webhook 的处理时间为 400-1200 毫秒。

有时,同一对象 ID 的多个 Hook 会在几微秒内相互发送。以下是最近发生的时间戳:

2020-11-21 12:42:45.812317+00:00
2020-11-21 20:03:36.881120+00:00 <-
2020-11-21 20:03:36.881119+00:00 <-

此时也可以发送其他对象进行处理。问题在于并发处理上面突出显示的两个 Hook 将为同一个对象创建两个新的数据库条目。

问:防止同时处理两个突出显示的条目的最佳方法是什么?

我尝试过的:目前,在传入 Hook 的开始,我在存储对象 ID 的 Changes 表中创建了一个数据库条目。在处理之前,检查 Changes 表以查找在过去 10 秒内为该 ID 创建的条目;如果找到一个,它就会退出,让另一个进程完成工作。

在上面的例子中,创建了两个数据库条目,因为它们在时间上非常接近,所以它们同时到达检测点,找到对方,然后退出,结果什么也没做。

我曾想过在检查前添加一些抖动超时(增加处理时间),或锁定表(同样,增加处理时间),但这一切感觉就像我在打一场错误的仗。

有什么建议吗?

我们的 API 是带有 Postgres 数据库的 Django 3.1

最佳答案

好吧,这可能不是一个非常令人满意的答案,但在我看来你的问题的根源不一定是你自己的应用程序,而是你从中接收的 webhooks 服务。

由于网络通信中固有的错误可能性,保证传递的网络钩子(Hook)总是使用至少一次语义。遇到导致接收不确定的故障的发件人需要再次尝试发送 webhook,即使 webhook 可能是第一次收到,从而打开了重复事件的可能性。

通过扩展,所有 webhook 发送服务都应该提供某种方法来删除单个事件的重复数据。我在 Stripe 帮助运行我们的 webhook,如果您使用这些,发送的每个 webhook 都会带有一个事件 ID,例如 evt_1CiPtv2eZvKYlo2CcUZsDcO6,接收方可以使用它进行重复数据删除。

因此,正确的答案是向您的发件人询问某种重复数据删除/幂等 key ,因为没有这些 key ,他们的 API 就不完整。

一旦有了它,一切就会变得非常简单:您可以在数据库中的那个键上创建一个唯一索引,然后使用 upsert以保证只有一个条目。这看起来像:

CREATE UNIQUE INDEX index_my_table_idempotency_key ON my_table (idempotency_key);

INSERT INTO object_changes (idempotency_key, ...) VALUES ('received-key', ...)
ON CONFLICT (idempotency_key) DO NOTHING;

第二好

如果没有用于重复数据删除的幂等性 ID,您的所有解决方案都将是 hacky,但您仍然可以找到一些可行的方法。您已经提出的尝试缩短接收时间的建议应该大部分都有效,尽管它仍然有可能丢失两个不同但在时间上接近的事件。

或者,您也可以尝试使用接收到的 webhook 的整个负载,或者更好的是,使用它的散列作为幂等 ID:

CREATE UNIQUE INDEX index_my_table_payload_hash ON my_table (payload_hash);

INSERT INTO object_changes (payload_hash, ...) VALUES ('<hash_of_webhook_payload>', ...)
ON CONFLICT (payload_hash) DO NOTHING;

这应该使该字段在数据库中保持相对较小,同时仍然保持准确的重复数据删除,即使对于紧密发送的唯一事件也是如此。

您也可以将两者结合起来:一个舍入的时间戳加上一个散列有效负载,以防万一您在某处收到一个具有相同有效负载的网络钩子(Hook)。唯一无法防止的是两个不同的事件在时间上非常接近地发送相同的有效负载,这种情况应该是不太可能发生的。

关于python-3.x - 处理 webhook 时的并发问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64948270/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com