如果在我们的数据库中修改了某些特定数据,我们的API需要将数据发送到Zapier。
例如,我们有一个公司表,如果修改了名称或地址字段,我们会触发Zapier挂钩。< / p>
有时我们的API会在几分钟内收到多个更改请求,但我们不想多次触发Zapier挂钩(因为它非常昂贵),所以我们调用setTimeout()
(并覆盖现有的) setTimeout
)对每个修改请求,5000ms
延迟。
它工作正常,即使我们在5000ms
期内收到客户端的大量修改请求,也没有多个Zapier挂钩调用。
现在 - 由于我们的流量正在增长 - 我们想在一些负载均衡器后面设置多个node.js实例。
但在这种情况下,不同的Node.js实例不能使用 - 并覆盖 - 相同的setTimeout
实例,这会导致很多无用的Zapier调用。
你们可以帮助我们,如何解决这个问题 - 同时保持可扩展性?
答案 0 :(得分: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);
}
}