Nodemon fs.writeFileSync 崩溃

Posted

技术标签:

【中文标题】Nodemon fs.writeFileSync 崩溃【英文标题】:Nodemon fs.writeFileSync Crash 【发布时间】:2019-05-27 10:56:40 【问题描述】:

我有一个来自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)

在 Windows 上使用 Visual Code Studio 进行测试时,效果很好。运行“nodemon myscript.js”并打开 localhost:3000 会显示该页面。随着事件的到来,nodemon 重新启动,页面无缝更新,事件从队列中清除。

但是,如果压缩文件和模块,并将脚本移动到 linux 机器上,通过 SSH 运行相同的脚本意味着我可以查看网页,页面得到更新,nodemon 重新启动并以相同的方式运行我期望的,但来自 SQS 队列的消息不会被删除。他们只是留在队列中,永远不会被删除。片刻之后,我的脚本会再次拉取它们,使网页不准确。他们将继续永远寻找并且永远不会删除。

如果我不使用 nodemon 或者如果我注释掉 fs.writeFileSync,应用程序将按预期工作,并且 SQS 队列中的事件将按预期删除。但是,我的网页没有更新。

我认为这是由于 nodemon 重新启动了服务,结果导致脚本在到达“deleteMessage”部分之前停止并重新启动。但是,如果我只是移动删除事件以使其在任何重置之前发生,它并不能解决问题。例如,以下代码在 Linux 上仍然存在问题,但与之前的版本一样,可以在 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) 解决此问题的最佳方法是什么,以确保我获得页面的实时更新,但事件被按预期删除?

【问题讨论】:

【参考方案1】:

1) 发生了什么,为什么会发生?

猜测:deleteMessage 是异步的,而写入文件的sync 操作会阻塞事件循环,因此您的 deleteMessage http 调用可能会被阻塞,并且当您重新启动进程时,它实际上从未执行过。

2) 为什么只有 Linux,而不是 Windows?

不知道。

3) 解决此问题的最佳方法是什么,以确保我获得实时更新 页面,但事件正在按预期删除?

我会直言不讳:您必须重做系统的所有架构。 自愿使您的网络服务器失败并重新启动它以刷新网页不会扩展到多个用户,甚至看起来也不会扩展到一个用户。它不应该那样工作。 根据您尝试构建的系统的限制(规模、速度等),许多不同的解决方案都可以工作。

尽可能简单:

第一个改进可能是保留您的文件存储,但通过 API 公开它以从 ajax 请求获取前端的数据,并定期轮询它。你会有更多的要求,但问题会少很多。它可能不太“实时”,但很少有系统实际上需要不到几秒钟的实时更新。

其次,不要在nodejs上做同步操作,这是一个巨大的性能瓶颈,会导致奇怪的错误和巨大的延迟。

当这样工作时,文件存储通常很痛苦,而且性能不高,可能会问自己是否需要数据库或 memcached/redis,也可以检查是否需要将网页中的轮询 API 替换为防止大量请求并允许不到 1 秒更新的套接字。

【讨论】:

以上是关于Nodemon fs.writeFileSync 崩溃的主要内容,如果未能解决你的问题,请参考以下文章

完成 fs.writeFilesync 时的回调

节点 fs.writeFileSync() 永远不会返回

fs.writeFileSync 不能在这里设置 DOCTYPE

fs.writeFileSync 给出错误:未知,在 nodejs 中进行同步文件写入的正确方法

nodejs写文件

[Node.js] Write or Append to a File in Node.js with fs.writeFile and fs.writeFileSync