node.js 集群,将子级标准输出重定向到文件中断数据

标签 node.js ubuntu redirect cluster-computing stdout

任务是:

  1. 集群创建工作线程
  2. 每个worker逐行加载一些远程数据并将其输出到自己的process.stdout
  3. 整个集群的输出被重定向到文件

预期结果:所有工作人员的所有行都连接到结果文件

实际结果:在某些机器上,结果与预期一致,在其他机器上,结果是交错的。

在 Ubuntu 操作系统下的 0.10.47 和 0.12.7 Node 上进行了测试。在 Ubuntu 16.04.2 下的两台机器上,结果很好。在 Ubuntu 14.04.5 下的一个上是交错的。

我需要帮助来了解这种情况并在 14.04 上修复它。

集群.js:

var cluster = require("cluster");

cluster.setupMaster({
    exec: "./worker.js"
});

cluster.fork();
cluster.fork();

worker.js:

var cluster = require("cluster");
var fs = require("fs");

var workerId = cluster.worker && cluster.worker.id || 1;
var stream = fs.createReadStream("./data" + workerId + ".log");

stream.on("end", function () {
    process.exit();
});

stream.pipe(process.stdout);

您需要在同一文件夹中包含两个名为 data1.log 和 data2.log 的文件来读取数据:

$ wc -l data*
     9260 data1.log
   111636 data2.log
   120896 total

管道总是给出良好的结果:

$ node cluster.js | wc -l
120896

重定向到文件仅在 Ubuntu 16.04 上给出了良好的结果,但在 Ubuntu 14.04 上却没有。在 Ubuntu 14.04 上更是如此,它每次都会给出不同的结果:

$ node cluster.js >result.log; wc -l result.log
114135      <= MUST BE 120896
$ node cluster.js >result.log; wc -l result.log
110136      <= MUST BE 120896

重定向到文件进行添加总是给出良好的结果:

$ rm result.log
$ node cluster.js >>result.log; wc -l result.log
120896

请注意,生成的文件小于原始文件。它的行数更少,字节更少。所以我认为来自不同 worker 的线路正在互相重写。

最佳答案

一般来说,您应该避免调用process.exit(),因为当您将数据缓冲发送到某个地方时,它可能会导致问题。 process.exit() 几乎立即结束进程。

在这种特殊情况下,很可能在进程退出之前 process.stdout 尚未完全刷新其内部缓冲区(当 process.stdout 写入是异步时)。

我的建议是允许工作进程自然退出,只需通过 process.disconnect() 断开工作进程中的(未使用的)IPC channel 并删除工作进程中的 process.exit() 即可。这应该允许 process.stdout 在进程退出之前完全耗尽/刷新。

关于node.js 集群,将子级标准输出重定向到文件中断数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43663065/

相关文章:

reactjs - 登录成功如何跳转?

javascript - node.js 中的 Redis 错误

node.js - 蒙哥错误: Can't project geometry into spherical CRS

node.js - eb create 错误:LargeZipFile::文件计数需要 ZIP64 扩展名

linux - 如何在 vim 中搜索 </string>?

mysql - 将 root 用户添加到 mysql wheel

php - 如何通过点击电子邮件中发送的超链接将用户重定向到移动应用程序或网站?是否需要使用 PHP 在服务器端处理?

php - 在magento中将http上的整个页面重定向到https

javascript - 如何获取正在运行的函数所属的对象名?

linux - 无法访问 virtualbox 中的串行端口设置