9.3クラスタの安定の道(『深入浅出nodejs』ノート)
4971 ワード
親子プロセスは、send()とon('message',calback)によってそれぞれメッセージの送信と受信処理を行うことで通信機構を実現する.
自動再起動は、メインプロセスにおいて、サブプロセスのexitイベントを傍受することによって、または開始された情報を知り、マルチプロセスアーキテクチャにおいて、いくつかのサブプロセス管理のメカニズムを追加し、例えば、プロセスを再起動してサービスを継続する. は、極端な状況において、すべての作業プロセスが新しい接続の受信を停止し、終了を待つ状態である.しかし、プロセスが完全に終了してから再起動するまでの間に、すべての新しい要求が新しいユーザに対して作業プロセスがない場合があります.これはほとんどの要求を破棄します.この時は終了の流れの中に自殺信号を追加する必要があります.仕事のプロセスは終了を知ると、メインプロセスに自殺信号を送ります.その後、新しい接続の受信を停止します.すべての接続が切断されてから退出します.メインプロセスは自杀信号を受信したら、すぐに新しいプロセスサービスを作成します. httpサービスの長時間接続には、既存の接続の切断にタイムアウト時間を設定する必要があり、制限時間内に強制終了する設定 捕獲できなかった異常をログ記録する .無意味な再起動をなくすために、一定の規則を満たす制限の下で、繰り返し再起動してはいけません.例えば、単位時間内に何回しか再起動できないと規定されています.制限を超えたらギブアップイベントを出発し、再起動を断念するという重要な事件をお知らせします.限定再起動の統計を達成するために、キューを使ってマークし、作業を再開するたびに打点し、再起動が頻繁すぎるかどうかを判断します.giveupイベントはuncaght Exceptionより深刻な異常を表しています.なぜなら、giveupイベントはクラスタ内にプロセスサービスがないことを示していますので、危険です.この時重要なログを追加して、監視システムにこの重大なエラーを監視させて、警察に通報します. デモ:
マスター.js(メインプロセス、コントロールと管理子プロセス) NODEデフォルトでは、オペレーティングシステムの占有戦略(つまり、cpu、I/Oの繁忙度を総合的に考慮して、処理サービスを行うかどうかを決定する)を採用しています.異なる業務については、cpuの繁忙度だけを考慮すればいいかもしれません. NODE v 0.11は、Round-Robinホイールのスケジューリングを提供し、その動作方式は、メインプロセスによって接続を受け付け、順次作業プロセスに配信する.配信のポリシーは、N個の作業プロセスにおいて、接続を送信するために、i=(i+1)mod n個のプロセスを選択するたびに行われる.clusterモジュールで有効にする方法は以下の通りです.
nodeは複数のプロセスの間でデータを共有することは許されないが、いくつかのデータは、例えば構成データは複数のプロセスの間で一致する必要がある.
1.第三者データストアを採用する
eg:redis、そして、ラウンドメッセージに格納されたデータ
2.自主的に通知する
通知プロセスを作成し、config設定をポーリングし、通知とクエリ状態を送信して他のプロセスに通知します.プッシュメカニズムはプロセス間の信号で転送できます.複数のサーバにまたがると無効になりますので、TcpまたはUDPの方式を採用することができます.
Clusterモジュール
clusterモジュールはchild_です.processとnetモジュールの組み合わせは応用します.ただし、clusterモジュールの応用では、一つのメインプロセスは一つの作業プロセスを管理するしかない.露出イベント: fork:作業プロセスをコピーした後、このイベントをトリガする online:作業プロセスをコピーした後、主プロセスがメッセージを受信した後、このイベントをトリガする listening:作業中にlisten(サーバのSocketを共有しました)を呼び出した後に、listeningメッセージをメインプロセスに送ります.メインプロセスはメッセージを受け取った後、このイベントをトリガします. disconnect:メインプロセスとワークプロセスの間のIPCチャネルが切断された後、このイベントをトリガすることができる . exit:ワークプロセスが終了したときにトリガするイベント setup:cluster.setupMaster()実行後、このイベントをトリガする場合のmaster.jsは以下のコードのみを書く必要があります.この場合、worker.jsでthrow new error を削除する必要があります.
自動再起動
マスター.js(メインプロセス、コントロールと管理子プロセス)
let fork = require('child_process').fork
let cpus = require('os').cpus()
let server = require('net').createServer()
server.listen(1337)
//
let limit = 10
//
let during = 60000
let restart = []
let isTooFrequently = function () {
//
let time = Date.now()
let length = restart.push(time)
if (length > limit) {
// 10
restart = restart.slice(limit * -1)
}
// 10
return restart.length >= limit && restart[restart.length - 1] - restart[0] < during
}
let workers = {}
let createWorker = function () {
//
if (isTooFrequently()) {
// giveup ,
process.emit('giveup', restart.length, during)
return
}
let worker = fork(__dirname + '/worker.js')
//
worker.on('message', function(message) {
if (message.act === 'suicide') {
createWorker()
}
})
//
worker.on('exit', function () {
console.log('Worker ' +worker.pid + ' exited.')
delete workers[worker.pid]
createWorker()
})
worker.send('server', server)
workers[worker.pid] = worker
console.log('Create worker.pid ' + worker.pid)
}
for(var i =0;i
ウォーカー.js(各作業プロセス)var http = require('http')
let logger = require('./logger')
let server = http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type':'text/plain'})
res.end('handled by child,pid is ' + 'process.pid' + '
')
throw new Error('throw exception ' + JSON.stringify(req))
})
let worker;
process.on('message', function(m, tcp) {
if(m === 'server') {
worker = tcp
worker.on('connection', function(socket) {
server.emit('connection',socket)
})
}
})
process.on('uncaughtException', function (err) {
logger.error(err)
process.send({act: 'suicide'}) //
//
worker.close(function () {
// ,
process.exit(1)
})
//
setTimeout(function() {
process.exit(1)
}, 5000)
})
負荷バランスcluster.schedulingPolicy = cluster.SCHED_RR ( Round-Robin)
cluster.schedulingPolicy = cluster.SCHED_NONE( )
または環境変数にNODE(u)を設定します.CLUSTERSCHEDPOLICYexport NODE_CLUSTER_SCHED_POLICY = rr
export NODE_CLUSTER_SCHED_POLICY = none
状態共有nodeは複数のプロセスの間でデータを共有することは許されないが、いくつかのデータは、例えば構成データは複数のプロセスの間で一致する必要がある.
1.第三者データストアを採用する
eg:redis、そして、ラウンドメッセージに格納されたデータ
2.自主的に通知する
通知プロセスを作成し、config設定をポーリングし、通知とクエリ状態を送信して他のプロセスに通知します.プッシュメカニズムはプロセス間の信号で転送できます.複数のサーバにまたがると無効になりますので、TcpまたはUDPの方式を採用することができます.
Clusterモジュール
clusterモジュールはchild_です.processとnetモジュールの組み合わせは応用します.ただし、clusterモジュールの応用では、一つのメインプロセスは一つの作業プロセスを管理するしかない.露出イベント:
let cluster = require('cluster')
cluster.setupMaster({
exec: "worker.js"
})
let cpus = require('os').cpus()
for(let i =0;i