【问题标题】:Access same setTimeout() instance from multiple Node.js instances从多个 Node.js 实例访问相同的 setTimeout() 实例
【发布时间】:2016-03-23 21:39:04
【问题描述】:

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

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

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

它工作正常,即使我们在此5000ms 期间收到来自客户端的大量修改请求,也没有多次 Zapier 挂钩调用。

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

但在这种情况下,不同的 Node.js 实例不能使用 - 并覆盖 - 同一个 setTimeout 实例,这会导致很多无用的 Zapier 调用。

你们能否帮助我们,如何解决这个问题 - 同时保持可扩展性?

【问题讨论】:

    标签: javascript node.js settimeout message-queue raft


    【解决方案1】:

    如果您想在不同的实例之间保持状态,您应该从基础架构的角度考虑一些锁定机制,例如 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);
    
      }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-21
      • 1970-01-01
      • 2022-07-30
      • 1970-01-01
      • 2011-06-04
      • 2018-09-16
      • 1970-01-01
      • 2023-04-07
      相关资源
      最近更新 更多