我有一个小节点脚本,可以在多个节点子进程中运行,而且我无权访问父进程。
脚本的目标非常简单,从数组中随机返回一个元素。但是,返回的元素不能被任何其他子进程使用。
我能想到的唯一解决方案是使用redis或数据库,因为这是一个非常小的脚本,我想避免这种情况。
以下是我希望代码看起来像的示例:
var accounts = [acc1, acc2, acc3]
function() {
var usedAccounts = sharedStore.get('usedAccounts')
var unusedAccounts = filter(accounts, usedAccounts)
var account = getRandomAccount(unusedAccounts)
usedAccounts.push(account)
sharedStore.set('usedAccounts', usedAccounts)
return account
}
到目前为止,我所认为的解决方案无法正常工作,因为兄弟流程最初都会获得分配给usedAccounts
的空列表。
答案 0 :(得分:2)
您需要解决两个问题:
如何在多个节点进程之间共享数据。
鉴于您不希望使用外部服务(如Redis或其他数据库服务)的约束,并且nodejs没有简单的方法来使用共享内存之类的东西,可能的解决方案是使用之间的共享文件所有的过程。每个进程都可以读取和写入共享文件,并使用它来获取userAccount
数据。
该文件可能是JSON格式的,如下所示:
[
{
"accountName":"bob",
"accountUsed":false
},
{
"accountName":"alice",
"accountUsed":true
}
]
这只是一个userAccount对象数组,它还有一个标志,指示是否正在读取数据。
你的app应该:
GetAccountData()
:
accountUsed
标志设置为true 有多个进程读取和写入单个资源是一个很好理解的并发问题,称为Readers-Writers Problem.
如何确保所有共享流程中的数据一致。
为确保数据一致,您需要确保一次只能有一个进程从头到尾运行算法。
操作系统可能会提供文件的独占锁定,但我对nodejs没有本机支持。
一种常见的机制是使用锁文件,并使用它来保护对上面数据文件的访问。如果它无法获取锁定,它应该等待一段时间,然后尝试重新获取锁定。
获得锁定:
GetAccountData();
这个解决方案应该可行,但它并非没有kludge。使用像锁一样的初始化可能会导致应用程序死锁。使用计时器定期获取锁定也是浪费,如果没有正确检查锁定,可能会导致竞争状态。
如果您的应用在删除锁定文件之前崩溃,那么您可能会创建死锁情况。为了防范这种情况,您可能希望放置一个最终未处理的异常处理程序,以便在该进程创建时删除该锁定文件。
您还需要确保只持有足够长的时间以进行连续工作。持有锁更长时间会导致性能问题,并增加死锁的可能性。
答案 1 :(得分:0)
我宁愿让每个进程都有自己的平面文件,他们可以编写。并且每个进程将能够同时读取所有进程写入的所有文件,否则将不需要锁定文件。 尽管您将不得不弄清楚每个进程如何仅写入自己的文件的逻辑,但是将所有这些文件一起读取将带出事实的真相