我有一个非常有趣的问题,我似乎无法解决。它实际上可能不是一个问题,而是内置于node.js中的东西。发送响应后,文件描述符的问题比预期的要长。在发送任何数据后,它们似乎在ESTABLISHED状态下持续最多2分钟。这导致我们的生产服务器出现问题。即使我们提供静态文件,一次可以打开的文件描述符的数量也可能非常高。他们经常达到我们的系统限制(linux)并导致EMFILE问题。我意识到我们可以修改1024以上的硬ulimit,但这似乎是一个针对不同问题的hacky修复。在套接字关闭时,我似乎应该释放文件描述符。
我有node.js版本:0.10.24
我能用少量代码复制这个问题。
http服务器:
var http = require("http"),
url = require("url"),
path = require("path"),
fs = require("fs")
port = process.argv[2] || 8888;
http.createServer(function(request, response) {
var uri = url.parse(request.url).pathname
, filename = path.join(process.cwd(), uri);
var contentTypesByExtension = {
'.html': "text/html",
'.css': "text/css",
'.js': "text/javascript"
};
path.exists(filename, function(exists) {
fs.readFile(filename, "binary", function(err, file) {
if(err) {
response.writeHead(500, {"Content-Type": "text/plain"});
response.write(err + "\n");
response.end();
return;
}
var headers = {};
var contentType = contentTypesByExtension[path.extname(filename)];
if (contentType) headers["Content-Type"] = contentType;
response.writeHead(200, headers);
response.write(file, "binary");
response.end();
});
});
}).listen(parseInt(port, 10));
console.log("Static file server running...");
```
向服务器发出请求。我提出了一个静态js文件的简单请求。在发出请求之前和之后监视文件描述符。
$ lsof -i -n -P | grep node
我的结果:
启动服务器之后和请求之前:
node 16787 ncswenson 11u IPv4 0x884c32306a467c65 0t0 TCP *:8888 (LISTEN)
请求完成后(请求后最多2分钟):
node 16787 ncswenson 11u IPv4 0x884c32306a467c65 0t0 TCP *:8888 (LISTEN)
node 16787 ncswenson 12u IPv4 0x884c32306a2773b5 0t0 TCP 127.0.0.1:8888->127.0.0.1:49399 (ESTABLISHED)
节点应该如何正常运行?在请求后保持文件描述符打开几分钟?有没有办法绕过这个问题?有没有办法更好地调查这个问题?