2016-05-09 5 views
3

this questionへの応答に基づいて、同じポート/アドレスに複数のワーカーがserver.listen()を呼び出しても問題は発生しませんが、古いワーカーコールがある理由を把握しようとしていますserver.close()続けて同じポート上のserver.listen()がエラーEADDRINUSEを繰り返し送信します。クラスタモジュールでネットポートを共有する

closeというイベントが発生したため、リスナーが正しく終了しない場合があります。これは、新しいリスナーを設定しようとしたときです。このワーカーはEADDRINUSEを取得していますが、新たに生まれたワーカーはserver.listen()に問題なく電話できます。

ここに、問題を示す簡単なテストがあります。労働者が100msごとにフォークされると、ポート16000にリスナーが確立されます。作業者10がフォークされると、1秒後にリスナーを解雇するタイムアウトが設定されます。 closeイベントが発行されると、再びポート16000のserver.listen()を呼び出して、EADDRINUSEエラーが発生します。一貫性を保つために、このテストでは、アドレスのnullを扱うコアモジュールの潜在的な問題を回避するために、バインディング時に明示的に同じアドレスを提供します。

この特定の実装により、ワーカー10は、バインディング中にエラーに遭遇した後にすべてのサイクルを使い、マスタープロセスが新しいワーカーをフォークするのを防ぎます。 server.listen()を呼び出す前に遅延が追加されていると、ワーカー10は引き続きEADDRINUSEにヒットしますが、マスターはリスナーを設定できる新しいワーカーを継続的にフォークします。このテストケースから

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(); 
} 

初期出力は:

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 
+0

V6.2.1で利用可能です(リスニングポートがランダムになることを意味しますが、すべての労働者は、同じランダムなポートを使用することになります)、エラーが投げられていないので、[このコード](https://github.com/nodejs/node/blob/cee4c25c9281d106f80b20ba7854bf9003f9357a/lib/net.js#L1310-L1315)がエラーの原因になっている可能性がありますAFAICSはポートに不一致があることを意味するので、意味がありません。 – robertklep

+0

16000ではなくポート0を使用すると、すべての初期リスナーが同じポート(私の場合は53230)に確立されますが、ワーカー10がポート0で別のリスナーを起動すると、最初の聴取の場合は53230、2番目の聴取の場合は53231など)。 –

+0

ああ、私はそれを認識しませんでした。これは、作業員の中で 'server.listen()'を2回目に呼び出すように聞こえるように思えます。 – robertklep

答えて

3

問題は、クラスタ・モジュールの内部であることが表示され、ノードのGithubにthis issueを介して追跡されています。

問題は更新され、修正されました。

更新:ポート0ではなく16000に耳を傾ける場合は、この修正プログラムは

関連する問題