我有一个来自AWS SQS service的数据队列,我正在检索此数据,将其发布到通过Node.js创建和托管的网页上,然后告诉SQS服务删除该文件。我使用Nodemon创建和更新页面,这样,每次我拉一个新事件时,页面就会更新,并且登录到该页面的用户会看到新数据。我使用类似以下代码的代码来实现这一点:
sqs.receiveMessage(data){
if (data = 1) {
dataForWebPage = something
fs.writeFileSync( "dataFile.json", JSON.stringify(dataForWebPage, null, 2), "utf8");
}
if (data = 2) {
dataForWebPage = somethingDifferent
fs.writeFileSync( "dataFile.json", JSON.stringify(dataForWebPage, null, 2), "utf8");
}
}
sqs.deleteMessage(data)
在使用Visual Code Studio的Windows上对此进行测试时,效果很好。运行“ nodemon myscript.js”并打开localhost:3000将显示该页面。当事件进入时,nodemon重新启动,页面进行无缝更新,并从队列中清除事件。
但是,如果将文件和模块压缩,并将脚本移至linux计算机上,则通过SSH运行相同的脚本意味着我可以查看网页,页面得到更新,nodemon重新启动并以相同的方式运行我所期望的,但是来自SQS队列的消息不会被删除。它们只是停留在队列中,并且永远不会被删除。片刻之后,我的脚本将再次拉动它们,从而使网页不准确。他们将永远看起来永远不会删除。
如果我不使用nodemon或注释掉fs.writeFileSync,则该应用程序将按预期运行,并且SQS队列中的事件将按预期删除。但是,我的网页然后没有更新。
我有一个理论,这是由于nodemon重新启动了服务,结果导致脚本在到达“ deleteMessage”部分之前停止并重新启动。但是,如果我只是移动delete事件,使其在任何重置之前发生,则不能解决问题。例如,以下代码在Linux上仍然无法使用,但是像以前的版本一样,DOES在Windows上也可以使用:
sqs.receiveMessage(data){
if (data = 1) {
dataForWebPage = something
sqs.deleteMessage(data)
fs.writeFileSync( "dataFile.json", JSON.stringify(dataForWebPage, null, 2), "utf8");
}
if (data = 2) {
dataForWebPage = somethingDifferent
sqs.deleteMessage(data)
fs.writeFileSync( "dataFile.json", JSON.stringify(dataForWebPage, null, 2), "utf8");
}
}
似乎如果我使用此调用的异步版本fs.writeFile,SQS事件也会按预期删除,但是由于收到很多事件,我正在使用此服务的同步版本来确保数据不会排队,并且会同时更新。
稍后在代码中,我使用fs.readFileSync,这似乎并不干扰删除SQS事件的调用。
我的问题是:
1)发生了什么,为什么发生了?
2)为什么只使用Linux,而不是Windows?
3)解决此问题的最佳方法是什么,以确保我可以实时更新页面,但事件已按预期删除?
答案 0 :(得分:0)
1)发生了什么,为什么发生了?
猜测:deleteMessage
是异步的,写文件的sync
操作阻止了事件循环,因此您的deleteMessage http调用可能被阻止,并且在重新启动该过程时,它实际上从未执行。
2)为什么只使用Linux,而不是Windows?
不知道。
3)解决此问题的最佳方法是确保我获得实时更新 页面,但是事件正在按预期方式删除?
我会直言不讳:您必须重做系统的所有体系结构。 自愿使您的Web服务器发生故障并重新启动以刷新网页将不会扩展到多个用户,甚至似乎也不会扩展到一个用户。这并不是要那样工作。 根据您尝试构建的系统约束(规模,速度等),可以使用许多不同的解决方案。
保持简单:
第一个改进可能是保留文件存储,但通过API公开文件以从ajax请求获取前端的数据,并定期进行轮询。您将有更多的请求,但问题更少。它可能不那么“实时”,但实际上很少有系统需要少于几秒钟的实时更新。
第二,不要在nodejs上执行同步操作,这是一个巨大的性能瓶颈,导致奇怪的错误和巨大的等待时间。
在这种情况下,文件存储通常会很麻烦,并且性能不佳,也许问自己是否需要数据库或内存缓存/ redis,还可以检查是否需要将轮询API从网页替换为套接字,它将阻止大量请求并允许少于1秒的更新。