【问题标题】:Nodejs process locks up reading from blocking FUSE fileNodejs进程锁定从阻塞FUSE文件中读取
【发布时间】:2014-05-06 15:04:24
【问题描述】:

我有一个 nodejs 网络服务器,它读取文件并提供内容。其中一些文件是 FUSE 虚拟文件,它们可能会在其后备服务等待数据提供时长时间阻止读取。

似乎如果这些读取请求中的 5 个堆积起来,则该进程将不再从任何文件中读取。另外,我不确定如何在必要时终止这些挂起的读取。

这是 nodejs 的限制,还是 FUSE 文件系统的行为与 FUSE 的预期不一致?

【问题讨论】:

  • 事实证明,FUSE 是无关紧要的,因为该行为有效地模拟了从尚未连接写入端的命名管道读取。 node.js 是否支持像这样从命名管道读取?

标签: javascript node.js fuse libuv


【解决方案1】:

根据this NodeJS issue report #7256,如果底层libuv I/O线程池中的线程尝试从阻塞的文件中读取,线程将挂起,直到支持目标文件的设备或进程将控制权交给线程,即读取调用返回。

此外,根据this libuv issue report #649,*nix 系统上的 NodeJS v0.10 依赖于默认大小为 4 的固定大小的线程池。这解释了为什么在大约 5 次读取尝试后系统似乎锁定了。

可以通过多种方式解决这种情况:

  1. 使用 UV_THREADPOOL_SIZE 环境变量增加底层 libuv 线程池的大小。这只是通过在 Node 进程开始受到影响之前允许更多读取机会来掩盖问题。

  2. 使用最近导出的 O_NONBLOCK 标志打开阻塞文件。此更改是 Node 0.10 代码流的一部分,我已确认它按预期工作(已从源代码编译 Node设置了 _XOPEN_SOURCE),但在发表此评论时不在最新的 0.10.28 版本中。相信非阻塞功能将成为 0.10.29 版本的一部分似乎是合理的。支持该文件的设备还必须尊重 O_NONBLOCK 标志才能正常工作。

一些代码来演示选项#2

var constants = process.binding('constants');
fs.open('/path/to/file', constants.O_NONBLOCK, function(err,fd){
    fs.read(fd, buf, 0, 10, null, function(err, bytesRead, buffer){
        // Read should return immediately
        if(err.code === 'EAGAIN'){
            // Not ready to read, try again later
        } else {
            // Do something
        }
    });
});

【讨论】:

    【解决方案2】:

    您是否使用readFileSync 来读取这些文件?如果是这样,那就是你的问题。

    节点应该能够等待大量资源,同时仍为请求提供服务。向我们展示您的代码以从文件中读取。

    【讨论】:

    • 我没有使用同步文件操作。这是读取调用:fs.read(self.fd, self.pool, 0, self.pool.length, null, onread); 如果数据可以从 FUSE 虚拟文件中轻松获得,或者文件描述符指向常规文件,它会正常工作并调用回调。如果虚拟文件阻塞,那么进程会明显变慢,直到它在 5 次未完成的读取时卡住。
    猜你喜欢
    • 1970-01-01
    • 2017-02-18
    • 1970-01-01
    • 1970-01-01
    • 2012-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多