2012-01-19 38 views
18

Hiện tại, môi trường prod của tôi cho một dự án phụ là một repo git, nơi tôi lấy một số mã, tự động giết máy chủ bằng Ctrl-C và khởi động lại theo cách thủ công.Làm cách nào để khởi động lại máy chủ NodeJS một cách duyên dáng?

Tôi nhận thấy có rất nhiều điều sai trái với điều này. Ví dụ, nếu một người dùng vẫn đang ở giữa làm điều gì đó quan trọng và quá trình này là crunching dữ liệu nhạy cảm, và tôi chỉ giết nó ?!

Khi tôi sử dụng nút v0.4.x có một mô-đun cụm đẹp có thể khởi động lại máy chủ một cách duyên dáng, khi ứng dụng ở trạng thái yên lặng. Trong v0.6.x mô-đun Cluster được xây dựng thành nút, nhưng nó thực sự, thực sự trần, và không có khả năng khởi động lại duyên dáng.

Bất kỳ ai cũng biết cách tôi có thể khởi động lại máy chủ nodejs một cách duyên dáng trong v0.6.x?

Trả lời

2

Có mô-đun có tên Forever.

Điều đó có thể khởi động lại quy trình một cách duyên dáng. Tôi giả sử sau đó bạn bằng cách nào đó có thể chạy một số trường hợp với cluster (một trên mỗi lõi) và sử dụng Forever để theo dõi/khởi động lại chúng.

Đây chỉ là một tùy chọn tôi đã tìm thấy; Tôi đang mở để gợi ý!

16

Bạn có thể xử lý tín hiệu POSIX trong mã nút.

Xem trong ví dụ mã, mà sẽ xử lý SIGINT (Ctrl-C chẳng hạn) như một tín hiệu STOP cho tất cả công nhân cụm, và SIGUSR2 sẽ chỉ khởi động lại tất cả các công nhân

Vì vậy, việc ban hành kill -SIGUSR2 PID, nơi PID là bậc thầy nút PID sẽ khởi động lại tất cả các cụm

module.exports = function(app) { 
    var cluster = require('cluster'); 
    var numCPUs = require('os').cpus().length; 
    var workerList = new Array(); 
    var sigkill = false; 

    if (cluster.isMaster) { 
     for (var i = 0; i < numCPUs; i++) { 
      var env = process.env; 
      var worker = cluster.fork(env); 
      workerList.push(worker); 
     } 

     process.on('SIGUSR2',function(){ 
      console.log("Received SIGUSR2 from system"); 
      console.log("There are " + workerList.length + " workers running"); 
      workerList.forEach(function(worker){ 
       console.log("Sending STOP message to worker PID=" + worker.pid); 
       worker.send({cmd: "stop"}); 
      }); 
     }); 

     process.on('SIGINT',function(){ 
      sigint = true; 
      process.exit(); 
     }); 

     cluster.on('death', function(worker) { 
      if (sigkill) { 
       logger.warn("SIGKINT received - not respawning workers"); 
       return; 
      } 
      var newWorker = cluster.fork(); 
      console.log('Worker ' + worker.pid + ' died and it will be re-spawned'); 

      removeWorkerFromListByPID(worker.pid); 
      workerList.push(newWorker); 
     }); 
    } else { 
     process.on('message', function(msg) { 
      if (msg.cmd && msg.cmd == 'stop') { 
       console.log("Received STOP signal from master"); 
       app.close(); 
       process.exit(); 
      } 
     }); 
     app.listen(3000); 
    } 

    function removeWorkerFromListByPID(pid) { 
     var counter = -1; 
     workerList.forEach(function(worker){ 
      ++counter; 
      if (worker.pid === pid) { 
       workerList.splice(counter, 1); 
      } 
     }); 
    } 
} 
+0

Trình xử lý 'SIGUSR2' có cần phải làm gì đó để khởi động lại quá trình mà nó vừa dừng lại không? –

+0

Ồ, tôi hiểu rồi ... Tôi nghĩ sự kiện 'chết' bây giờ là 'thoát' trong Node v0.10? –

+0

Một câu hỏi nữa ... điều này khởi động lại máy chủ một cách duyên dáng, nhưng nó không tải lại mã máy chủ, đúng không? Điều đó sẽ mất một số loại quá trình giám sát bên ngoài? –

1

Còn có một mô-đun có tên PM2. Nó có khả năng ngăn chặn tất cả các tiến trình trong một cụm.

+0

-1; Tôi đã thử khả năng tải lại "duyên dáng" của PM2 và theo như tôi có thể nói nó [chỉ đơn giản là không hoạt động] (https://github.com/Unitech/pm2/issues/3078) ngay bây giờ. Tôi không thể hứa rằng bất kỳ câu trả lời nào khác ở đây hoạt động tốt hơn, nhưng tôi * chắc chắn rằng câu trả lời này là một kết thúc bực bội và lãng phí thời gian. –

Các vấn đề liên quan