diff --git a/doc/api/cluster.markdown b/doc/api/cluster.markdown index 11c48cefc0c69f..a71a6ed68e67ca 100644 --- a/doc/api/cluster.markdown +++ b/doc/api/cluster.markdown @@ -2,12 +2,23 @@ Stability: 2 - Unstable + +一つの io.js インスタンスは一つのスレッドで実行されます。 +マルチコアシステムのメリットを生かすために、 +ユーザは時々 io.js プロセスのクラスを起動して負荷を分散したくなります。 + + + +クラスタモジュールは、サーバポートを共有する複数の子プロセスを簡単に +構築することを可能にします。 var cluster = require('cluster'); var http = require('http'); @@ -31,7 +42,11 @@ all share server ports. }).listen(8000); } + + +io.js は 8000 番ポートをワーカ間で共有します。 % NODE_DEBUG=cluster iojs server.js 23521,Master Worker 23524 online @@ -39,43 +54,91 @@ Running io.js will now share port 8000 between the workers: 23521,Master Worker 23523 online 23521,Master Worker 23528 online + + +この機能は最近導入されたばかりであり、 +将来のバージョンで変更される可能性があります。 +これを試して、フィードバックを行ってください。 + + +Windows では、ワーカが名前付きパイプによるサーバをセットアップすることは +まだできないことにも注意してください。 ## How It Works + + +ワーカプロセスは `child_process.fork` メソッドを使って起動されるため、 +親プロセスと IPC で通信したり、サーバハンドルをやり取りしたりすることが +できます。 + + +クラスタモジュールは到着する接続を分散する方法を二種類提供します。 + +一つ目 (Windows 以外の全てのプラットフォームでデフォルト) +はラウンドロビン方式で、マスタプロセスがポートをリッスンし、 +新しい接続を受け付けるとラウンドロビン方式でワーカに分散します +(ワーカの過負荷を避ける工夫が組み込まれています)。 + + + +二つ目の方法は、マスタプロセスがリスニングソケットを作成し、 +ワーカに送信します。ワーカは到着する接続を直接受け付けます。 + + +二つ目の方法は、原則的には、ベストなパフォーマンスであるべきです。 +しかし実際には、OS の予測不可能なスケジューラにより、 +非常に不均衡に分散される傾向があります。 +全 8 プロセス中の 2 プロセスに 70% 以上の接続が割り当てられたことも +観測されました。 + +`server.listen()` は仕事の大部分をマスタプロセスに渡すため、 +通常の io.js プロセスとクラスタのワーカプロセスの間には +振る舞いが異なるケースが 3 つあります。 + + + +1. `server.listen({fd: 7})` メッセージはマスタに渡されてるため、 + ワーカのファイル記述子 7 が参照するものではなく、 + **親プロセスの** ファイル記述子 7 がリスニングされてそのハンドルがワーカに + 渡されます。 +2. `server.listen(handle)` 明示的なハンドルをリスニングするとマスタプロセスは + 関与することなく、ワーカは与えられたハンドルを使うことになります。 + ワーカがすでにハンドルを持っているなら、何をしようとしているか + あなたは分かっているでしょう。 +3. `'server.listen(0)` 通常、これはサーバがランダムなポートをリッスンすることを + 意味します。しかしながらクラスタでは、各ワーカは `listen(0)` によって + 同じ "ランダムな" ポートを受信します。 + すなわち、初回はポートはランダムになりますが、その後はそうではありません。 + もしユニークなポートをリッスンしたければ、クラスタのワーカ ID に基づいて + ポート番号を生成してください。 + + + +io.js にもあなたのプログラムにも、ルーティングのためのロジックや +ワーカ間で共有される状態はありません。 +したがって、あなたのプログラムがセッションやログインのためにメモリ内の +データオブジェクトに過度に頼らないように設計することが重要です。 + + +全てのワーカは独立したプロセスなので、他のワーカに影響を与えることなく +プログラムのニーズに応じてそれらを殺したり再起動したりすることができます。 +いくつかのワーカが生きている限り、サーバは接続を受け付け続けます。 +しかしながら、io.js はワーカの数を自動的に管理することはありません。 +アプリケーションのニーズに応じてワーカのプールを管理することは、 +あなたの責務です。 ## cluster.schedulingPolicy + + +スケジューリングポリシーは、ラウンドロビンの `cluster.SCHED_RR` または、 +OS に任せる `cluster.SCHED_NONE` のどちらかです。 +これはグローバルな設定で、その効果は最初のワーカを起動する時か、 +`cluster.setupMaster()` を呼び出した時、どちらかが最初に行われた時点で +凍結されます。 + +`SCHED_RR` は Windows 以外の全ての OS でデフォルトです。 +Windows では、libuv が大きなパフォーマンス低下を招くことなく +IOCP ハンドルを分散することが可能であれば、`SCHED_RR` に切り替わります。 + + + +`cluster.schedulingPolicy` は、`NODE_CLUSTER_SCHED_POLICY` 環境変数を +通じて設定することもできます。適切な値は `"rr"` または `"none"` です。 ## cluster.settings + +* {Object} + * `execArgv` {Array} node 実行ファイルに渡される引数を表す、文字列の配列 + (デフォルトは `process.execArgv`)。 + * `exec` {String} ワーカで実行するファイルへのパス + (デフォルトは `process.argv[1]`)。 + * `args` {Array} ワーカに渡される引数となる文字列 + (デフォルトは `process.argv.slice(2)`)。 + * `silent` {Boolean} 出力を親プロセスに送るかどうか + (デフォルトは `false`)。 + * `uid` {Number} このプロセスのユーザ識別子を設定します + (setuid(2) を参照)。 + * `gid` {Number} このプロセスのグループ識別子を設定します + (setgid(2) を参照)。 + + + +`.setupMaster()` (または `.fork()`) が呼び出された後、この `settings` +オブジェクトはデフォルト値を含む設定オブジェクトを持ちます。 + + +`.setupMaster()` は一度しか呼び出せないため、それは設定された後で事実上 +凍結されます。 + + +このオブジェクトはあなたによって変更されることを想定していません。 ## cluster.isMaster * {Boolean} + + +現在のプロセスがマスタの場合は `true` です。 +これは `process.env.NODE_UNIQUE_ID` から決定されます。 +`process.env.NODE_UNIQUE_ID` が未定義だと `isMaster` は `true` になります。 ## cluster.isWorker * {Boolean} + + +このプロセスがマスタでなければ `true` (これは `cluster.isMaster` の否定です)。 ## Event: 'fork' * `worker` {Worker object} + + +新しいワーカがフォークされると、クラスタモジュールは `'fork'` イベントを +生成します。 +これはワーカの活動をロギングしたり、タイムアウトのために使うことができます。 var timeouts = []; function errorMsg() { @@ -180,10 +340,17 @@ This can be used to log worker activity, and create your own timeout. * `worker` {Worker object} + + +新しいワーカをフォークした後、ワーカはオンラインメッセージを応答します。 +マスタがオンラインメッセージを受信すると、このイベントが生成されます。 +`'fork'` と `'online'` の違いは、`'fork'` はマスタがワーカをフォークした時点で +生成されるのに対し、`'online'` はワーカが実行されてから生成される点です。 cluster.on('online', function(worker) { console.log("Yay, the worker responded after it was forked"); @@ -194,36 +361,73 @@ master forks a worker, and 'online' is emitted when the worker is running. * `worker` {Worker object} * `address` {Object} + + +ワーカが `net.Server.listen()` を呼び出した後、(net や http などの) サーバでは +`'listening'` イベントが生成され、マスタの `cluster` でも `'listening'` +イベントが生成されます。 + + +イベントハンドラは二つの引数を伴って実行されます。 +`worker` はワーカオブジェクトを、`address` オブジェクトは +以下の接続プロパティを含みます: +`address`、`prot`、そして `addressType` です。 +これはワーカが複数のアドレスをリッスンしている場合にとても便利です。 cluster.on('listening', function(worker, address) { console.log("A worker is now connected to " + address.address + ":" + address.port); }); + + +`addressType` は以下のいずれかです: + + +* `4` (TCPv4) +* `6` (TCPv6) +* `-1` (unix ドメインソケット) +* `"udp4"` または `"udp6"` (UDP v4 または v6) ## Event: 'disconnect' * `worker` {Worker object} + + +ワーカとの IPC チャネルが切断された後で生成されます。 +それはワーカが自然に終了したり、殺されたり、あるいは (`worker.disconnect()` +により) 手動で切断された場合に発生します。 + + +`'disconnect'` と `'exit'` の間には遅延があるかもしれません。 +このイベントはプロセスがクリーンナップで行き詰まったり、長時間生きている接続が +ないかを検出することに使用できます。 cluster.on('disconnect', function(worker) { console.log('The worker #' + worker.id + ' has disconnected'); @@ -231,14 +435,30 @@ long-living connections. ## Event: 'exit' + +* `worker` {Worker object} +* `code` {Number} 正常に終了した場合は終了コード。 +* `signal` {String} プロセスが殺される原因となったシグナルの名前 + (例: `'SIGHUP'`)。 + + + +どのワーカが死んだ場合でも、クラスタモジュールは `'exit'` イベントを +生成します。 + + +これは `.fork()` を呼び出してワーカを再開する場合に使用することができます。 cluster.on('exit', function(worker, code, signal) { console.log('worker %d died (%s). restarting...', @@ -252,36 +472,82 @@ See [child_process event: 'exit'](child_process.html#child_process_event_exit). * `settings` {Object} + + +`setupMaster()` は呼ばれた時に毎回生成されます。 + + +`settings` オブジェクトは同時に `cluster.settings` オブジェクトでもあります +`.setupMaster()` は呼び出されると報告するだけで、複数回の呼び出し以降 +`.setupMaster()` は単一のイベントループで実行することが出来ます。 + + +精度が重要な場合は、`cluster.settings`を使用します。 ## cluster.setupMaster([settings]) + +* `settings` {Object} + * `exec` {String} ワーカで実行するファイルへのパス. + (デフォルトは `process.argv[1]`) + * `args` {Array} ワーカに渡される引数となる文字列。 + (デフォルトは `process.argv.slice(2)`) + * `silent` {Boolean} 出力を親プロセスに送るかどうか。 + (デフォルトは `false`) + + + +`setupMaster()` は 'fork' のデフォルト動作を変更するために使われます。 +一度呼び出されると、その設定は `cluster.settings` に反映されます。 + +注意事項: + + + +* すべての設定変更は将来の `.fork()` の呼び出し時にのみ影響を与え、すでに +実行されているワーカには影響を与えません +* `.setupMaster()` から設定できない *唯一の* ワーカの属性は +`.fork()`に渡される `env` です。 +* 上記のデフォルトは最初の呼び出しだけ適用され、以降の呼び出しのデフォルト +は `cluster.setupMaster()` が呼ばれた時の値です + + +例: var cluster = require('cluster'); cluster.setupMaster({ @@ -295,36 +561,80 @@ Example: }); cluster.fork(); // http worker + + +これはマスタプロセスからのみ、呼び出すことができます。 ## cluster.fork([env]) + + +* `env` {Object} ワーカプロセスの環境に加えられるキーと値のペア。 +* return {Worker object} + +新しいワーカプロセスを起動します。 + + + +これはマスタプロセスからのみ呼び出すことができます。 ## cluster.disconnect([callback]) + + +* `callback` {Function} 全てのワーカが切断し、ハンドルがクローズされると + 呼び出されます。 + +`cluster.workers` 内の各ワーカに対して `.disconnect()` を呼び出します。 + + + +ワーカとの接続が切断して内部的なハンドルが全てクローズされると、 +他に待機しているイベントがなければ、マスタプロセスは自然に終了します。 + +このメソッドはオプションの引数としてコールバックを受け取ります。 + + + +これはマスタプロセスからのみ呼び出すことができます。 ## cluster.worker * {Object} + + +現在のワーカオブジェクトへの参照です。 +マスタプロセスでは利用できません。 var cluster = require('cluster'); @@ -340,14 +650,27 @@ A reference to the current worker object. Not available in the master process. * {Object} + + +`id` をキーとしてアクティブなワーカオブジェクトを保存しているハッシュです。 +これは全てのワーカに対して繰り返しを行うことを容易にします。 +マスタプロセスでのみ利用可能です。 + + +ワーカは disconnect し exit した後で `cluster.workers` から削除されます。 +これら二つのイベントの順序は、事前に決定することができません。 +けれども、それは最後の `'disconnect'` か `'exit'` イベントが生成される前に +`cluster.workers` のリストから削除されることを保証します // Go through all workers function eachWorker(callback) { @@ -359,8 +682,13 @@ before last `'disconnect'` or `'exit'` event is emitted. worker.send('big announcement to all workers'); }); + + +通信チャネルを越えてワーカの参照を渡す場合は、 +ワーカのユニークな ID を使ってワーカを探すのが簡単です。 socket.on('data', function(id) { var worker = cluster.workers[id]; @@ -368,43 +696,87 @@ the worker's unique id is the easiest way to find the worker. ## Class: Worker + + +ワーカに関する全ての公開された情報やメソッドを持つオブジェクトです。 +マスタでは `cluster.wrokers` から取得することができます。 +ワーカでは `cluster.worker` から取得することができます。 ### worker.id * {String} + + +新しいワーカはいずれもユニークな ID を与えられます。 +この ID は `id` に保存されます。 + +ワーカが生きている間、これは `cluseter.workers` のキーとなります。 ### worker.process * {ChildProcess object} + + +全てのワーカは `child_process.fork()` によって作成されます。 +その戻り値は `.process` に設定されます。 +ワーカでは、グローバルの `process` に設定されます。 + + + +参照: [Child Process module]( +child_process.html#child_process_child_process_fork_modulepath_args_options) + + + +`process` で `'disconnect'` イベントが生成されるとワーカが `process.exit(0)` +を呼び出し、`.suicide` が `true` にならないことに注意してください。 +これは偶発的な切断を防ぎます。 ### worker.suicide * {Boolean} + + +`.kill()` または `.disconnect()` によって設定されます。 +それまでは `undefined` です。 + + + +真偽値の `worker.suicide` は、ワーカが自発的に終了したのか偶発的に終了したのかを +区別します。 +マスタはこの値に基づいて、ワーカを再起動しないことを選ぶことができます。 cluster.on('exit', function(worker, code, signal) { if (worker.suicide === true) { @@ -420,13 +792,29 @@ exit, the master may choose not to respawn a worker based on this value. * `message` {Object} * `sendHandle` {Handle object} + + +この関数は `child_process.fork()` が返すオブジェクトの `send()` +メソッドと同じです。 +マスタは特定のワーカにメッセージを送信するためにこの関数を +使用することができます。 + + +ワーカでは `process.send(message)` を使うこともできます。 +それは同じ関数です。 + + +この例はマスタからのメッセージをエコーバックします。 if (cluster.isMaster) { var worker = cluster.fork(); @@ -440,47 +828,113 @@ This example will echo back all messages from the master: ### worker.kill([signal='SIGTERM']) + + +* `signal` {String} ワーカプロセスに送られるシグナルの名前です。 + + +この関数はワーカを終了します。 +マスタでは、これは `worker.process` と切断することによって行われます。 +そして切断されると、`signal` によってワーカを殺します。 +ワーカでは、これはチャネルの切断によって行われ、コード `0` で終了します。 + +`.suicide` が設定される原因となります。 + + + +後方互換性のため、このメソッドには `worker.destroy()` という別名があります。 + + +ワーカでは、`process.kill()` は存在するものの、それは関数ではないことに +注意してください。 +[kill](process.html#process_process_kill_pid_signal) を参照してください。 ### worker.disconnect() + + +ワーカでは、この関数は全てのサーバをクローズし、それらのサーバの `'close'` +イベントを待機し、そして IPC チャネルを切断します。 + +マスタでは、ワーカが自分の `.disconnect()` を呼び出すことになる内部メッセージを +ワーカに送ります。 + + + +`.suicide` が設定される原因となります。 + + +サーバがクローズした後、それはもう新たな接続を受け付けなくなりますが、 +他のワーカによって接続は受け付けられることに注意してください。 +既存のコネクションは通常通りクローズすることができます。 +コネクションが無くなると ([server.close()](net.html#net_event_close) 参照)、 +ワーカが自然に終了できるように IPC チャネルはクローズされます。 + +上記はサーバ側のコネクションにのみ適用されます。 +クライアント側のコネクションはワーカによって自動的にクローズされることはなく、 +終了する前にそれらがクローズすることを待つこともありません。 + + + +ワーカでは、`process.disconnect` は存在しますが、それはここで説明した関数では +ありません。それは +[disconnect](child_process.html#child_process_child_disconnect) です。 + + +長時間生きているサーバ側のコネクションはワーカが切断することを妨げるため、 +それらをクローズするためにアプリケーション固有のメッセージを送ることは有用です。 +加えて、一定の時間が経過しても `'disconnect'` イベントが発生しなかった場合に +ワーカを強制終了する実装も有用です。 if (cluster.isMaster) { var worker = cluster.fork(); @@ -515,25 +969,50 @@ the `disconnect` event has not been emitted after some time. ### worker.isDead() + + +ワーカプロセスが終了している場合、この関数は `true` をを返します (終了して +いるか通知されているかいずれかにより)。それ以外の場合は `false` を返します。 ### worker.isConnected() + + +ワーカが IPC チャネルを経由してマスターに接続している場合、この関数は +`true` を返す。それ以外の場合は `false` を返します。 +ワーカは作成された後マスターに接続されます。それは `disconnect` イベント +が生成された後切断されます。 ### Event: 'message' * `message` {Object} + + +このイベントは `child_process.fork()` が提供するものと同じです。 + +ワーカでは、`process.on('message')` を使うこともできます。 + + + +メッセージシステムを使用してクラスタ全体のリクエスト数を +マスタプロセスで保持する例です: var cluster = require('cluster'); var http = require('http'); @@ -577,29 +1056,49 @@ in the master process using the message system: ### Event: 'online' + + +`cluster.on('online')` と同様ですが、このワーカに特化しています。 cluster.fork().on('online', function() { // Worker is online }); + + +このイベントはワーカでは生成されません。 ### Event: 'listening' * `address` {Object} + + +`cluster.on('listening')` と同様ですが、このワーカに特化しています。 cluster.fork().on('listening', function(address) { // Worker is listening }); + + +このイベントはワーカでは生成されません。 ### Event: 'disconnect' + + +`cluster.on('disconnect')` と同様ですが、このワーカに特化しています。 cluster.fork().on('disconnect', function() { // Worker has disconnected @@ -607,12 +1106,23 @@ Similar to the `cluster.on('disconnect')` event, but specfic to this worker. ### Event: 'exit' + + +* `code` {Number} 正常に終了した場合は終了コード。 +* `signal` {String} プロセスが殺される原因となったシグナルの名前 + (例: `'SIGHUP'`)。 + + +`cluster.on('exit')` と同様ですが、このワーカに特化しています。 + var worker = cluster.fork(); worker.on('exit', function(code, signal) { if( signal ) { @@ -626,6 +1136,14 @@ Similar to the `cluster.on('exit')` event, but specific to this worker. ### Event: 'error' + + +このイベントは `child_process.fork()` が提供するものと同じです。 + + +ワーカでは `process.on('error')` を使うこともできます。