关于程序员:一次node文件操作过多排查过程总结

5次阅读

共计 1870 个字符,预计需要花费 5 分钟才能阅读完成。

  • 前端进阶之旅:https://interview2.poetries.top
  • 博客:https://blog.poetries.top
  • 公众号 / 小程序:「前端进阶之旅」每天分享技术干货,学前端不迷路
  • 作者:程序员 poetry

大家好,我是 poetry。最近在优化公司外部的脚手架,遇到一个问题,Error: EMFILE, too many open files也就是 nodejs 关上文件过多会导致谬误,一次次排查,最初找到了一个无效的办法,总结记录一下

当我尝试去操作大量文件的时候

for(var i=0; i<200000; i++) {fq.readFile('./somefile.txt', {encoding: 'utf8'}, function(err, somefile) {console.log("data from somefile.txt without crashing!", somefile);
    });
}

以上导致 Error: EMFILE: too many open files 谬误。我不用敞开文件,因为显然能够 fs.readFile 对文件进行操作并为我敞开文件。我在 Mac OS 上,我的 ulimit 设置为8192

$ ulimit -a
-t: cpu time (seconds)              unlimited
-f: file size (blocks)              unlimited
-d: data seg size (kbytes)          unlimited
-s: stack size (kbytes)             8192
-c: core file size (blocks)         0
-v: address space (kbytes)          unlimited
-l: locked-in-memory size (kbytes)  unlimited
-u: processes                       1392
-n: file descriptors                256

能够通过批改系统配置,然而不太举荐

$ echo kern.maxfiles=65536 | sudo tee -a /etc/sysctl.conf
$ echo kern.maxfilesperproc=65536 | sudo tee -a /etc/sysctl.conf
$ sudo sysctl -w kern.maxfiles=65536
$ sudo sysctl -w kern.maxfilesperproc=65536
$ ulimit -n 65536 
  • 因为 node.js 的异步个性,因而会产生此谬误。过程试图关上的文件超出容许的数量,因而会产生谬误。
  • 能够通过创立关上 文件队列 来解决此问题,以使它们永远不会超过限度,以下是一些能够为您实现此操作的库:

咱们能够应用文件队列来限度每次关上的文件数量

Instantiate Filequeue with a maximum number of files to be opened at once (default is 200)

how to use

var FileQueue = require('filequeue');
var fq = new FileQueue(100);

// additional instances will attempt to use the same instance (and therefore the same maxfiles)

var FileQueue2 = require('filequeue');
var fq2 = new FileQueue2(100);

console.log(fq === fq2); // => true

// you can force a new instance of filequeue with the `newQueue` parameter

var fq3 = new FileQueue(100, true);

console.log(fq === fq3); // => false

filequeue 反对以下办法

readFile
writeFile
readdir
rename
symlink
mkdir
stat
exists
createReadStream
createWriteStream

应用 filequeue 就能够失常运行了

var FileQueue = require('filequeue');
var fq = new FileQueue(100); // 限度每次关上的文件数量

for(var i=0; i<200000; i++) {fq.readFile('./demo.txt', {encoding: 'utf8'}, function(err, somefile) {console.log("data from somefile.txt without crashing!", somefile);
    });
}

本文由 mdnice 多平台公布

正文完
 0