【发布时间】:2019-02-21 03:39:19
【问题描述】:
我有一个在单个服务器上运行的 nodejs 应用程序。我需要在多台服务器上运行应用程序以实现负载平衡。
此应用一次仅处理来自特定用户的单个请求。如果同时收到来自用户的请求,则这些请求将被排队并一个接一个地执行。这样做是为了保持数据库中某些数据的一致性,如果应用同时处理请求,这些数据会被破坏。
由于我要在多台服务器上运行应用程序,我需要一种方法来防止服务器同时处理来自单个用户的请求。为此,我使用了 firebase 实时数据库来构建分布式锁。以下是我的代码的更简单版本。
function lockUser(user) {
return firebaseAdmin.database().ref('users/' + user + '/lock').transaction((currentData) => {
if (currentData === null || currentData.lockTime === 0) {
return {'lockTime': Date.now()};
}
}, null, false).then(async (result) => {
if (result.committed) {
return Promise.resolve();
}
log.info('failed to lock ' + user + '. retrying.');
await sleepFor(500);
return lockUser(user, user, res);
}).catch(async (reason) => {
log.info('lock failed. ' + user + '. reason: ' + reason + '. retrying');
await sleepFor(500);
return lockUser(user, user, res);
});
}
function unlockUser(user) {
log.info('unlocking firebase lock. ' + user);
firebaseAdmin.database().ref('users/' + user + '/lock').set({'lockTime': 0}, (error) => {
if (error) {
log.warn('failed to unlock ' + user + '. error: ' + util.inspect(error));
} else {
log.info('unlocked ' + user);
}
});
}
使用上面的代码,一个锁通常需要大约 100 毫秒,并且大部分是一致的。但很少有时,我会观察到完成交易的明显延迟。发生这种情况时,锁定可能需要大约 30 秒。
延迟的原因可能是什么?我有什么理由不应该以这种方式使用 firebase 实时数据库?
【问题讨论】:
标签: node.js firebase firebase-realtime-database firebase-admin