在Node.js脚本中,我试图打开一些端口/套接字,然后再次将其关闭。使用Node.js群集模块时遇到麻烦。在不使用集群模块时,似乎没有以与相同代码相同的方式关闭端口。
例如,采用以下代码,该代码在其自己的端口上分别创建5个http.Server,然后关闭除最后一个(第5个)之外的所有端口。
'use strict';
var http = require('http');
function goGoGadget(i) {
console.log('var i = ', i);
var httpServer = http.createServer();
var nextPort = 4000 + i;
console.log('about to listen on port', nextPort);
httpServer.listen(nextPort);
if (i < 5) {
httpServer.on('listening', function() {
console.log('closing port:', nextPort);
httpServer.close(function() {
console.log('closed server on port:', nextPort);
});
});
}
}
goGoGadget(1);
goGoGadget(2);
goGoGadget(3);
goGoGadget(4);
goGoGadget(5);
与预期的一样,node.js仅打开了一个端口:
dhcp50:test marco$ lsof -i -n -P | grep node
node 20895 marco 16u IPv4 0xb242422d2e0e2bb1 0t0 TCP *:4005 (LISTEN)
然后,使用相同的代码,但使用“群集”模块在工作程序中运行:
'use strict';
var cluster = require('cluster');
var http = require('http');
function goGoGadget(i) {
console.log('var i = ', i);
var httpServer = http.createServer();
var nextPort = 4000 + i;
console.log('about to listen on port', nextPort);
httpServer.listen(nextPort);
if (i < 5) {
httpServer.on('listening', function() {
console.log('closing port:', nextPort);
httpServer.close(function() {
console.log('closed server on port:', nextPort);
});
});
}
}
if (cluster.isMaster) {
var numWorkers = 5;
for (var i = 0; i < numWorkers; i += 1) {
console.log ('forking ', i + 1);
cluster.fork();
}
}
else {
goGoGadget(cluster.worker.id);
}
这次,Node.js会保留前四个http.Server的端口,即使它们已关闭:
dhcp50:test marco$ lsof -i -n -P | grep node
node 20900 marco 17u IPv4 0xb242422d2d9682e1 0t0 TCP *:4004 (LISTEN)
node 20900 marco 18u IPv4 0xb242422d2d5faa11 0t0 TCP *:4001 (LISTEN)
node 20900 marco 19u IPv4 0xb242422d2d5fd621 0t0 TCP *:4005 (LISTEN)
node 20900 marco 20u IPv4 0xb242422d2d985141 0t0 TCP *:4002 (LISTEN)
node 20900 marco 21u IPv4 0xb242422d2d9862e1 0t0 TCP *:4003 (LISTEN)
node 20905 marco 13u IPv4 0xb242422d2d5fd621 0t0 TCP *:4005 (LISTEN)
我的问题很简单:为什么?以及如何关闭它们?我怀疑如果我在net.Server.listen()中使用了独占选项,则端口可能会关闭,但是http.Server.listen() API似乎并未将此选项哈希作为参数。
这个问题的起源来自一个问题:当使用幻影节点(带有phantomjs)在使用Cluster模块的Express.js应用程序中随时间打开许多页面时。为了确保在创建新的幻像节点实例时不会发生端口冲突,并且要避免EADDRINUSE
,我进行了端口扫描,并检查了我要使用的端口是否可用。问题在于,随着时间的流逝,越来越多的端口被打开,并且由于它们从未关闭过,因此节点最终会因EMFILE
错误而崩溃。
看来,所描述的问题是通过Node v0.11.1出现的。从0.11.2起,套接字在关闭时已成功取消链接。通过此提交修复。
凉爽的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句