9.3クラスタの安定の道(『深入浅出nodejs』ノート)

4971 ワード

親子プロセスは、send()とon('message',calback)によってそれぞれメッセージの送信と受信処理を行うことで通信機構を実現する.
自動再起動
  • は、メインプロセスにおいて、サブプロセスのexitイベントを傍受することによって、または開始された情報を知り、マルチプロセスアーキテクチャにおいて、いくつかのサブプロセス管理のメカニズムを追加し、例えば、プロセスを再起動してサービスを継続する.
  • は、極端な状況において、すべての作業プロセスが新しい接続の受信を停止し、終了を待つ状態である.しかし、プロセスが完全に終了してから再起動するまでの間に、すべての新しい要求が新しいユーザに対して作業プロセスがない場合があります.これはほとんどの要求を破棄します.この時は終了の流れの中に自殺信号を追加する必要があります.仕事のプロセスは終了を知ると、メインプロセスに自殺信号を送ります.その後、新しい接続の受信を停止します.すべての接続が切断されてから退出します.メインプロセスは自杀信号を受信したら、すぐに新しいプロセスサービスを作成します.
  • httpサービスの長時間接続には、既存の接続の切断にタイムアウト時間を設定する必要があり、制限時間内に強制終了する設定
  • 捕獲できなかった異常をログ記録する
  • .
  • 無意味な再起動をなくすために、一定の規則を満たす制限の下で、繰り返し再起動してはいけません.例えば、単位時間内に何回しか再起動できないと規定されています.制限を超えたらギブアップイベントを出発し、再起動を断念するという重要な事件をお知らせします.限定再起動の統計を達成するために、キューを使ってマークし、作業を再開するたびに打点し、再起動が頻繁すぎるかどうかを判断します.giveupイベントはuncaght Exceptionより深刻な異常を表しています.なぜなら、giveupイベントはクラスタ内にプロセスサービスがないことを示していますので、危険です.この時重要なログを追加して、監視システムにこの重大なエラーを監視させて、警察に通報します.
  • デモ:
    マスター.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) })
    負荷バランス
  • NODEデフォルトでは、オペレーティングシステムの占有戦略(つまり、cpu、I/Oの繁忙度を総合的に考慮して、処理サービスを行うかどうかを決定する)を採用しています.異なる業務については、cpuの繁忙度だけを考慮すればいいかもしれません.
  • NODE v 0.11は、Round-Robinホイールのスケジューリングを提供し、その動作方式は、メインプロセスによって接続を受け付け、順次作業プロセスに配信する.配信のポリシーは、N個の作業プロセスにおいて、接続を送信するために、i=(i+1)mod n個のプロセスを選択するたびに行われる.clusterモジュールで有効にする方法は以下の通りです.
  • cluster.schedulingPolicy = cluster.SCHED_RR (  Round-Robin)
    cluster.schedulingPolicy = cluster.SCHED_NONE(   )
    
    または環境変数にNODE(u)を設定します.CLUSTERSCHEDPOLICY
    export 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モジュールの応用では、一つのメインプロセスは一つの作業プロセスを管理するしかない.露出イベント:
  • fork:作業プロセスをコピーした後、このイベントをトリガする
  • online:作業プロセスをコピーした後、主プロセスがメッセージを受信した後、このイベントをトリガする
  • listening:作業中にlisten(サーバのSocketを共有しました)を呼び出した後に、listeningメッセージをメインプロセスに送ります.メインプロセスはメッセージを受け取った後、このイベントをトリガします.
  • disconnect:メインプロセスとワークプロセスの間のIPCチャネルが切断された後、このイベントをトリガすることができる
  • .
  • exit:ワークプロセスが終了したときにトリガするイベント
  • setup:cluster.setupMaster()実行後、このイベントをトリガする場合のmaster.jsは以下のコードのみを書く必要があります.この場合、worker.jsでthrow new error
  • を削除する必要があります.
    let cluster = require('cluster')
    
    cluster.setupMaster({
      exec: "worker.js"
    })
    let cpus = require('os').cpus()
    for(let i =0;i