我有一个使用koa的节点应用程序。它从外部应用程序接收特定资源上的webhook。

为了说明这一点,假设webhook通过POST请求向我发送了以下类型的对象:

{
  'resource_id':'<SomeID>',
  'resource_origin':'<SomeResourceOrigin>',
  'value' : '<SomeValue>'
}


我想顺序执行来自同一来源的任何资源,以避免与我的执行相关的资源不同步。

我当时在考虑使用数据库作为锁,并使用cron对相同来源的每个资源依次执行我的进程。

但是我不确定这是最有效的方法。

所以我的问题在这里:

您是否知道一些方法/包/服务,允许我使用可以为每个起源实现的全局队列,以确保来自相同起源的资源将被同步执行,而无需按顺序处理所有Webhooks?如果不使用数据库,那就更好了。

最佳答案

如果我是您,那么我将从序列化所有Webhooks的处理开始。换句话说,无论您来自何处,我都建议您一次处理它们。在您的nodejs应用程序中使用一个简单的队列。

(一旦您确信自己可以正常工作,则可以根据来源对它们进行序列化。)

首先,构造函数(将其称为handleOneWebhook())以将传入的Webhooks作为Promise或异步函数进行处理。然后,您可以使用具有此大纲的代码来调用它们。

let busy= false
async function handleManyWebhooks (queue) {
    if (busy) return
    busy = true
    while (queue.length > 0) {
        const item = queue.shift()
        await handleOneWebhook (item)
    }
    busy  = false
}


传递给queuehandleManyWebhooks是一个简单的数组,其中每个元素都是POST请求中的对象。您将其用作队列:push()每个对象将其放入队列,并shift()将其删除。

然后,每当您收到一个webhook POST对象时,就使用带有此轮廓的代码。

const queue = []
...

function handlePostObject (postObject) {
   queue.push(postObject)
   handleManyWebooks (queue)
}


即使您为每个传入的对象调用一次handleManyWebhooks,busy标志也可以确保它一次仅处理一个。

注意,这是一个非常简单的解决方案。一旦它正常工作,就会提出两个可能的改进。


使用比简单数组更有效的队列。 shift()不太快。
为每个单独的来源创建一个具有自己的busy标志的单独的队列对象。然后,您将能够并行化处理来自不同来源的Webhooks,同时仍然序列化来自每个来源的Webhooks流。

关于node.js - 顺序执行 Node 应用程序中收到的Webhook,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56823472/

10-10 01:17