从多个 Node.js 个实例访问相同的 setTimeout() 实例
Access same setTimeout() instance from multiple Node.js instances
如果在我们的数据库中修改了某些特定数据,我们的 API 需要将数据发送到 Zapier。
例如,我们有一个 company table,如果 name 或 address 字段被修改,我们触发了 Zapier 钩子。
有时我们的 API 在几分钟内收到多个更改请求,但我们不想多次触发 Zapier 挂钩(因为它非常昂贵),所以我们调用 setTimeout()
(并覆盖现有的 setTimeout
)每个修改请求,延迟 5000ms
。
它工作正常,即使我们在这个 5000ms
期间收到来自客户端的大量修改请求,也没有多次 Zapier 挂钩调用。
现在 - 由于我们的流量在增长 - 我们想在某些负载均衡器后面设置多个 node.js 实例。
但在这种情况下,不同的 Node.js 实例不能使用 - 并覆盖 - 相同的 setTimeout
实例,这会导致很多无用的 Zapier 调用。
你们能帮助我们,如何解决这个问题 - 同时保持可扩展性?
如果你想在不同的实例之间保持状态,从基础设施的角度来看,你应该考虑一些锁定机制,比如 Redis。
每当你想 运行 Zapier 调用时,如果没有锁处于活动状态,你在 Redis 上设置一个,所有其他调用都不会被触发,因为它被锁定,每当 setTimeout
回调 运行s,你禁用了锁定。
请注意,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);
}
}
如果在我们的数据库中修改了某些特定数据,我们的 API 需要将数据发送到 Zapier。
例如,我们有一个 company table,如果 name 或 address 字段被修改,我们触发了 Zapier 钩子。
有时我们的 API 在几分钟内收到多个更改请求,但我们不想多次触发 Zapier 挂钩(因为它非常昂贵),所以我们调用 setTimeout()
(并覆盖现有的 setTimeout
)每个修改请求,延迟 5000ms
。
它工作正常,即使我们在这个 5000ms
期间收到来自客户端的大量修改请求,也没有多次 Zapier 挂钩调用。
现在 - 由于我们的流量在增长 - 我们想在某些负载均衡器后面设置多个 node.js 实例。
但在这种情况下,不同的 Node.js 实例不能使用 - 并覆盖 - 相同的 setTimeout
实例,这会导致很多无用的 Zapier 调用。
你们能帮助我们,如何解决这个问题 - 同时保持可扩展性?
如果你想在不同的实例之间保持状态,从基础设施的角度来看,你应该考虑一些锁定机制,比如 Redis。
每当你想 运行 Zapier 调用时,如果没有锁处于活动状态,你在 Redis 上设置一个,所有其他调用都不会被触发,因为它被锁定,每当 setTimeout
回调 运行s,你禁用了锁定。
请注意,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);
}
}