与群集模块共享networking端口

基于对这个问题的回答 ,我试图找出为什么有多个工作者调用server.listen()在同一个端口/地址不会导致任何问题,但有一个老工人调用server.close()由同一个端口上的server.listen()会反复给出错误EADDRINUSE

这似乎不是一个监听器没有正确closures的情况,因为发出close事件,这是当我尝试build立新的监听器。 当这名工作人员得到EADDRINUSE ,新产生的工人可以调用server.listen()而不会造成任何问题。

这是一个简单的testing,将certificate这个问题。 由于工作人员每隔100ms分叉一次,他们将在端口16000上build立一个监听器。当工作人员10分叉时,它将build立一个超时,在1秒后将其监听器拆除。 一旦发生close事件,它将尝试再次在端口16000上调用server.listen()并获取EADDRINUSE错误。 为了保持一致性,该testing在绑定过程中明确提供了相同的地址,以避免核心模块处理null地址时出现任何潜在的问题。

这个特定的实现将导致工作人员10在绑定过程中遇到错误后接着执行所有的循环,从而使主进程免于分派新的工作人员。 如果在调用server.listen()之前添加了一个延迟,那么worker 10将继续击中EADDRINUSE同时主服务器不断地EADDRINUSE能够build立侦听器的新工作人员。

 var cluster = require('cluster'); var net = require('net'); if (cluster.isMaster) { setInterval(function(){cluster.fork()},100); } else { var workerID = cluster.worker.id; var server; var setup = function() { console.log('Worker ' + workerID + ' setting up listener'); server = net.createServer(function(stream) {}); server.on('error', function(err) { console.log('Error on worker ' + workerID, err); teardown(); }); if (workerID == 10) { server.listen(16000, '127.0.0.1', function() { console.log('Worker ' + workerID + ' listener established'); setTimeout(teardown, 1000); }); } else { server.listen(16000, '127.0.0.1', function() { console.log('Worker ' + workerID + ' listener established'); }); } } var teardown = function() { console.log('Worker ' + workerID + ' closing listener'); server.close(setup); } setup(); } 

这个testing用例的初始输出:

 Worker 1 setting up listener Worker 1 listener established Worker 2 setting up listener Worker 2 listener established Worker 3 setting up listener Worker 3 listener established Worker 4 setting up listener Worker 4 listener established Worker 5 setting up listener Worker 5 listener established Worker 6 setting up listener Worker 6 listener established Worker 7 setting up listener Worker 7 listener established Worker 8 setting up listener Worker 8 listener established Worker 9 setting up listener Worker 9 listener established Worker 10 setting up listener Worker 10 listener established Worker 11 setting up listener Worker 11 listener established Worker 12 setting up listener Worker 12 listener established Worker 13 setting up listener Worker 13 listener established Worker 14 setting up listener Worker 14 listener established Worker 15 setting up listener Worker 15 listener established Worker 16 setting up listener Worker 16 listener established Worker 17 setting up listener Worker 17 listener established Worker 18 setting up listener Worker 18 listener established Worker 19 setting up listener Worker 19 listener established Worker 10 closing listener Worker 10 setting up listener Error on worker 10 { [Error: bind EADDRINUSE 127.0.0.1:16000] code: 'EADDRINUSE', errno: 'EADDRINUSE', syscall: 'bind', address: '127.0.0.1', port: 16000 } Worker 10 closing listener Worker 10 setting up listener Error on worker 10 { [Error: bind EADDRINUSE 127.0.0.1:16000] code: 'EADDRINUSE', errno: 'EADDRINUSE', syscall: 'bind', address: '127.0.0.1', port: 16000 } Worker 10 closing listener 

这个问题似乎是集群模块的内部问题,并且正在通过节点Github上的这个问题进行跟踪。

问题现在已经更新,并已修复。

更新:此修补程序在v6.2.1中可用