Javascript 从多个Node.js实例访问同一个setTimeout()实例

Javascript 从多个Node.js实例访问同一个setTimeout()实例,javascript,node.js,settimeout,message-queue,raft,Javascript,Node.js,Settimeout,Message Queue,Raft,如果数据库中的某些特定数据被修改,我们的API需要向Zapier发送数据 例如,我们有一个company表,如果name或address字段被修改,我们将触发Zapier钩子 有时我们的API在几分钟内收到多个更改请求,但我们不想多次触发Zapier钩子(因为它非常昂贵),因此我们在每个修改请求上调用setTimeout()(并覆盖现有的setTimeout),延迟5000ms 它工作得很好,即使在这个5000ms期间我们从客户机收到很多修改请求,也不会有多个Zapier钩子调用 现在,由于我们

如果数据库中的某些特定数据被修改,我们的API需要向Zapier发送数据

例如,我们有一个company表,如果name或address字段被修改,我们将触发Zapier钩子

有时我们的API在几分钟内收到多个更改请求,但我们不想多次触发Zapier钩子(因为它非常昂贵),因此我们在每个修改请求上调用
setTimeout()
(并覆盖现有的
setTimeout
),延迟
5000ms

它工作得很好,即使在这个
5000ms
期间我们从客户机收到很多修改请求,也不会有多个Zapier钩子调用

现在,由于我们的流量在增长,我们想在一些负载平衡器后面设置多个node.js实例

但是在这种情况下,不同的Node.js实例不能使用并覆盖相同的
setTimeout
实例,这将导致大量无用的Zapier调用


<>你能帮助我们,如何解决这个问题——在保持可扩展性的情况下?

如果你想在单独的实例之间保持一个状态,你应该从基础设施的角度考虑一些锁定机制,比如ReDIS。 每当你想运行Zapier调用时,如果没有锁处于活动状态,你就在Redis上设置一个,所有其他调用都不会被触发,因为它被锁定了。每当
setTimeout
回调运行时,你就禁用锁。 当心ReDIS可能成为SPOF,我不知道您在哪里托管您的服务,但这可能是一个重要的考虑点。 编辑:

Redis上的锁可能引用了您要更新的最后一条信息。因此,在第一次请求时,您将数据设置为保存在Redis上,等待5秒钟,然后进行更新。如果在该时间段内进行了任何修改,它将存储在Redis上,这样您只需每隔5秒更新一次,但您需要在此处添加一些额外的逻辑。例如:

function zapierUpdate(data) {

  if (isLocked()) {

    // Locked! We will update the data that needs to be saved on the
    // next setTimeout callback
    updateLockData(data);

  } else {

    // First lock and save data.
    lock(data);
    // and update in 5 seconds
    setTimeout(function(){
      // getLockData fetches the data on Redis and releases the lock
      var newData = getLockData();
      // Update the latest data that might have been updated.
      callZapierNow(newData);
    },5000);

  }

}