Node.js實現100%線上的要則
這是針對NodeJS的生產環境中如何保證100%線上不停機的文章。
1.使用Domain模組處理未捕獲的異常
未捕獲的異常發生時,錯誤被丟擲一個try/ catch塊以外,或者一個錯誤事件發出後,並沒有誰去偵聽它。NodeJS對待未捕獲異常的預設操作是退出崩潰的程式,如果這個程式是一個伺服器,就導致伺服器停機,所以我們要儘可能避免未捕獲的異常,並且在它們發生時明智地處理它們。
使用Domain編寫堅固的程式碼和測試來完成這個一目的。NodeJS的Domain模組.
Domain的方法有:
add: 繫結一個發射器到domain.
run: 在domain場景下執行
bind: 繫結一個函式
intercept: 類似繫結但是不處理第一個引數錯誤
dispose: 取消IO 和 timers.
使用Domain的案例:
// create a top-level domain for the server var serverDomain = domain.create(); serverDomain.run(function() { // server is created in the scope of serverDomain http.createServer(function(req, res) { // req and res are also created in the scope of serverDomain // however, we'd prefer to have a separate domain for each request. // create it first thing, and add req and res to it. var reqd = domain.create(); reqd.add(req); reqd.add(res); reqd.on('error', function(er) { console.error('Error', er, req.url); try { res.writeHead(500); res.end('Error occurred, sorry.'); } catch (er) { console.error('Error sending 500', er, req.url); } }); }).listen(1337); }); <p class="indent"> |
執行一個普通函式的案例:
var d = domain.create(); d.on('error', function(er) { console.error('Caught error!', er); }); d.run(function() { process.nextTick(function() { setTimeout(function() { // simulating some various async stuff fs.open('non-existent file', 'r', function(er, fd) { if (er) throw er; // proceed... }); }, 100); }); }); <p class="indent"> |
domain能夠捕獲非同步錯誤:
var d = require('domain').create(); d.on('error', function (err) { console.log("domain caught", err); }); var f = d.bind(function() { console.log(domain.active === d); // <-- true throw new Error("uh-oh"); }); setTimeout(f, 100); <p class="indent"> |
上述f函式如果不繫結在domain場景下執行,其丟擲的錯誤會使NodeJS崩潰,這裡domain的錯誤處理器被呼叫,給你一個機會採取行動,比如重試忽略等。
當程式碼在Domain中執行時,domain是活動的,你可以透過domain.active 包含引用它,新的事件發射器將繫結到這個活動的domain。
2.使用cluster管理程式
domain並不足以完成持續線上不當機,有時一個獨立的程式因為一些錯誤需要停止,使用NodeJS的Cluster模組,我們能分配一個主程式管理一個或多個工作程式,並且分佈工作給它們,主程式需要不停止的一直執行,意味著socket總是能接受連線,當一個worker工作程式停止工作,主程式能替代它。
當我們初始化一個工作程式的載入好後,我們使用傳送訊號給主程式,可以給主程式分配Unix的符號連結symlink指向工作者程式碼,然後更新符號連結指向到一個新的程式碼版本,傳送訊號給主程式讓它關閉一箇舊的工作程式,開啟新的工作程式,新的工作程式將用新的程式碼版本執行。
主程式和工作程式的協調通訊很重要,工作程式使用它們狀態進行通訊,主程式必須知道基於這些狀態採取何種行動,recluster是對node的原生cluster模組一個的包裝,能提供工作程式的狀態管理。
當工作程式需要關閉時,它們必須優雅地關閉,因為它們服務於很多請求,有大量的tcp連線,為了關閉這些存在的連線,我們必須增加中介軟體來檢查應用是否可以進入一個正在關閉的狀態,如果是就立即關閉。
var afterErrorHook = function(err) {
server.close(); // <-- ensure no new connections
}
呼叫server.close能確保沒有新的連線
下面是關閉一個正在活動的程式:
var afterErrorHook = function(err) { // <-- called after an unrecoverable error app.set("isShuttingDown", true); // <-- set state server.close(function() { process.exit(1); // <-- all clear to exit }); } var shutdownMiddle = function(req, res, next) { if(app.get("isShuttingDown") { // <-- check state req.connection.setTimeout(1); // <-- kill keep-alive } next(); } <p class="indent"> |
我們可以在一個計時器timer中呼叫process.exit。
相關文章
- node.js中的模組實現原理Node.js
- Node.js 流的使用及實現Node.js
- 電腦科學領域實現男女平等 還要100年
- 文件線上預覽的實現
- 線上直播系統原始碼,Node.js中使用Koa實現上傳圖片功能原始碼Node.js
- node.js利用socket.io實現多人線上匹配聯機五子棋Node.js
- Node.js Writable Stream的實現簡析Node.js
- 你要懂的SMART原則
- 單件模式的實現要點模式
- node.js 用socket實現聊天Node.js
- [原] 探索 EventEmitter 在 Node.js 中的實現MITNode.js
- Node.js Readable Stream的實現簡析Node.js
- JS實現線上ps功能JS
- jQuery實現線上文件jQuery
- java文件線上播放實現Java
- Redis雜湊表的實現要點Redis
- 遞迴實現原則遞迴
- 本人告訴你為什麼 現在還要學 Node.jsNode.js
- Node.js Stream 流的使用及實現總結Node.js
- Node.js中TCP及聊天室的實現Node.jsTCP
- 利用node.js實現的多圖上傳功能Node.js
- 使用正則實現 getType方法
- 正則實現數學運算
- 四則運算實現 (轉)
- Java中動態規則的實現方式Java
- 從零搭建 Node.js 線上環境Node.js
- Node.js原始碼解析-Readable實現Node.js原始碼
- node.js實現爬蟲功能介紹Node.js爬蟲
- 走進Node.js 之 HTTP實現分析Node.jsHTTP
- Node.js的Koa實現JWT使用者認證Node.jsJWT
- node.js的express模組實現GET和POST請求Node.jsExpress
- node.js實現的自定義事件程式碼例項Node.js事件
- Multidex(分包)實現簡要分析IDE
- undo segment的建立、線上以及extent的分配原則。
- 線上生成短連結的原因及實現工具
- Python實現多人線上匿名聊天的小程式Python
- 從零開始實現線上直播
- Android實現線上播放音樂Android