[Node.js] Availability and Zero-downtime Restarts
2023-09-14 09:00:49 时间
It might be possible for our node server has some downtime, no matter it is because server update or simply some crashs in the code. We want to minizie the downtime as much as possible.
1. In case of cluster worker crash, we want master worker fork a new worker:
const http = require('http'); const cluster = require('cluster'); const os = require('os'); if (cluster.isMaster) { const cpus = os.cpus().length; console.log(`Forking for ${cpus} CPUs`); for (let i = 0; i < cpus; i++) { cluster.fork(); } cluster.on('exit', (worker, code, signal) => { if (code !== 0 && !worker.exitedAfterDisconnect) { console.log(`Worker ${worker.id} crashed. Starting a new wroker`); cluster.fork(); } }) } else { require('./server'); }
It is important to check 'worker.exitedAfterDisconnect' to see whether is is because crash or because we want to exit one worker.
2. In case of upgrade, we want to restart each worker one by one, to make zero downtime:
// kill -SIGUSR2 <MASTER_PID> // In case to upgrade, we want to restart each worker one by one process.on('SIGUSR2', () => { const workers = Object.values(cluster.workers); const restartWorker = (workerIndex) => { const worker = cluster.workers[workerIndex]; if (!worker) return; // On worker exit, we want to restart it, then continue // with next worker worker.on('exit', () => { // If it is because crash, we don't continue if (!worker.exitedAfterDisconnect) return; console.log(`Exited process ${worker.process.pid}`); cluster.fork().on('listening', () => { restartWorker(workerIndex + 1); }); worker.disconnect(); }); } // Calling restartWorker recursively restartWorker(0); });
In really production, we don't actually need to code cluster by ourselve, we can use PM2 package. but it is important to understand what's happening under hood.
---
const cluster = require('cluster'); const http = require('http'); const os = require('os'); // For runing for the first time, // Master worker will get started // Then we can fork our new workers if (cluster.isMaster) { const cpus = os.cpus().length; console.log(`Forking for ${cpus} CPUs`); for (let i = 0; i < cpus; i++) { cluster.fork(); } // In case of crash, we want to strat a new worker cluster.on('exit', (worker, code, signal) => { if (code !== 0 && !worker.exitedAfterDisconnect) { console.log(`Worker ${worker.id} crashed. Starting a new wroker`); cluster.fork(); } }) // kill -SIGUSR2 <MASTER_PID> // In case to upgrade, we want to restart each worker one by one process.on('SIGUSR2', () => { const workers = Object.values(cluster.workers); const restartWorker = (workerIndex) => { const worker = cluster.workers[workerIndex]; if (!worker) return; // On worker exit, we want to restart it, then continue // with next worker worker.on('exit', () => { // If it is because crash, we don't continue if (!worker.exitedAfterDisconnect) return; console.log(`Exited process ${worker.process.pid}`); cluster.fork().on('listening', () => { restartWorker(workerIndex + 1); }); worker.disconnect(); }); } // Calling restartWorker recursively restartWorker(0); }); } else { require('./server'); }
相关文章
- Node.js系列-http
- 【nodejs原理&源码赏析(6)】深度剖析cluster模块源码与node.js多进程(下)
- Node.js其他模块
- Node.js自定义对象事件监听与发射
- Node.js之HTPP URL
- Node.js链式回调
- 让我欲罢不能的node.js
- [Docker] Create a Node.js Non-root Image
- [CLI] Create a Hybrid Single-Multi Command Node.js CLI with Oclif and TypeScript
- [Custom CLI] Develop and Publish a Node.js CLI from Scratch
- [Docker] Linking Node.js and MongoDB Containers
- [Tools] Batch Create Markdown Files from a Template with Node.js and Mustache
- [Tools] Convert SVG to a PDF in Node with PDFKit and SVG.js
- [Node.js] Web Scraping Images with Node, Xray, and Download
- [MEAN Stack] First API -- 1. with Node.js, Express and MongoDB
- [Node.js] Level 3 new. Steam
- Node.js模块 require和 exports
- 前端 JS,localStorage/sessionStorage、cookie 及 url 等实现前台数据共享、传输
- node.js实现国标GB28181设备接入的sip服务器解决方案
- Node.js 和 C++ 之间的类型转换
- [Custom CLI] Develop and Publish a Node.js CLI from Scratch
- [Node.js] Read a File in Node.js with fs.readFile and fs.readFileSync
- [Node.js] Intro to Web Scraping with Node and X-ray
- [Node.js] Level 5. Express
- [Node.js]26. Level 5 : Route rendering
- React.js 应用 UI 框架
- webpack中引入的path[require('path')]是node.js内置的package,用来处理路径的。
- node.js常见的一些错误信息
- atitit 新特性与趋势管理的艺术 v2 s52.docx 1. lang语言系列 java node.js php 2 1.1. Atitit js es5 es6新特性 attilax总结
- 如何使用 multiparty 工具库在 Node.js 应用里解析 multipart form-data 格式的请求
- Node.js 环境下的 console.log 是同步执行的