fs.writeFile在高负载下挂起(v.0.6.6上没有错误)

我们正在尽可能多地提出请求,并且每个请求都写一个文件。 对于小负载工作正常,但在高负载情况下,同步版本仍然正常工作,asynchronous版本(fs.writeFile)挂起。 节点停止提供请求并将大部分文件保留为0大小(大多数都不会被创build)。

在v0.6.6中没有错误

在v.0.4.7中,我们得到了:

{ stack: [Getter/Setter], arguments: undefined, type: undefined, message: 'EMFILE, Too many open files \'aw_1031\'', errno: 24, code: 'EMFILE', path: 'aw_1031' } 

Ubuntu(VM)和Mac Osx中的行为相同。

这是我们当前运行的示例脚本:

 ab -n 30000 -c 500 http://HOST:8000/ 

filetest.js

 var http = require('http'); var fs = require('fs'); var util = require ('util'); var i=0; function writeALot(req, res){ fs.writeFile("filetest"+i, "Just a try: "+i, function(err){ if(err) console.log(util.inspect(err)); }); i++; res.writeHead(200); res.end(); } http.createServer(writeALot).listen(8000); 

我们如何pipe理并发fd的最大数量? 有什么build议?

提前致谢。

那么文件描述符的数量是有限的(http连接也是文件描述符)。 在每个连接中,将会写入一个文件,这将是500个并发的1000个文件描述符。 可能你的ulimit -n是1024.实际上你可以增加限制,这是我见过的人为生产高并发服务器所做的。 除此之外,你可以创build一个小于500的并发队列。我在一个使用async模块的应用程序中做了这个。 对我提出的每个要求设置一个上限。 这将保存我正在创build的文件描述符,但不包含传入的连接。

 var queue = async.queue(function(task, cb) { console.log('processing', task.method, queue.length(), task.addr) if(task.method === 'file') { makeFileStream(task); } else { makeRequest(task); } }, 500); 

然后,如果我想提出请求或打开一个文件,

 queue.push({ method : 'file', // or request task : 'something' }); 

也有这种方式: http : //nodebits.org/distilled-patterns

但是使用队列的批处理的例子并不好。