Zero-downtime 部署:为什么这对您的 JavaScript 服务至关重要?
\n\n想象一下:周五晚上,您正在部署一个 Node.js 的新功能——一分钟后,技术支持聊天室里就充斥着恐慌的消息:“网站挂了!”,“500 错误!”,“数据丢失了!”。熟悉吗?如果您的 JavaScript 服务在更新期间停止响应,您不仅会失去用户,还会损失金钱和声誉。
\n\nZero-downtime 部署(零停机部署)是一种让用户无感知的代码更新方法。所有请求都得到处理,连接不会中断,新代码平稳上线。对于依赖异步和事件的 Node.js 来说,这一点尤其重要:一次突然的中断可能导致内存泄漏或未处理的 Promise。
\n\n在本文中,我将展示如何在实际操作中配置 JavaScript 服务的无缝部署。我们将通过真实的代码示例,详细讲解三种实用的策略——滚动更新、蓝绿部署和优雅关闭。开始吧!
\n\n策略 1:滚动更新——不停机更新
\n\n滚动更新——Node.js 世界中最流行的技术。原理很简单:您运行着多个应用程序实例,然后逐个更新它们。当一个实例重启时,其他实例继续处理流量。
\n\n实际工作原理
\n假设您有 4 个通过 PM2(一个流行的进程管理器)启动的 Node.js 进程。命令 pm2 reload app 会自动执行滚动重启:逐个终止进程并启动新代码。但为了确保无错误运行,您需要正确配置 优雅关闭(详见下文)。
PM2 零停机配置示例
\n在项目根目录创建一个 ecosystem.config.js 文件:
module.exports = {\n apps: [{\n name: 'my-javascript-service',\n script: './server.js',\n instances: 4, // 4 个实例\n exec_mode: 'cluster', // 集群模式\n wait_ready: true, // 等待 ready 信号\n listen_timeout: 5000, // 就绪超时时间\n kill_timeout: 5000, // 终止超时时间\n max_restarts: 10,\n env: {\n NODE_ENV: 'production'\n }\n }]\n};\n\n\n然后在服务器代码 (server.js) 中添加信号处理:
const http = require('http');\nconst app = require('./app'); // 您的 Express/Koa 应用\n\nconst server = http.createServer(app);\nconst PORT = process.env.PORT || 3000;\n\nserver.listen(PORT, () => {\n console.log(`服务器在端口 ${PORT} 上启动`);\n // 向 PM2 发送进程就绪信号\n if (process.send) {\n process.send('ready');\n }\n});\n\n// 优雅关闭\nprocess.on('SIGINT', () => {\n console.log('收到 SIGINT,开始优雅关闭...');\n server.close(() => {\n console.log('HTTP 服务器已关闭');\n process.exit(0);\n });\n});\n\nprocess.on('SIGTERM', () => {\n console.log('收到 SIGTERM,正在终止...');\n server.close(() => {\n console.log('HTTP 服务器已关闭');\n process.exit(0);\n });\n});\n\n\n现在,当执行 pm2 reload ecosystem.config.js 时,PM2 将逐个停止并启动实例,等待 ready 信号。用户不会察觉到切换。
滚动更新的优缺点
\n- \n
- + 无需额外的服务器或代理。 \n
- + 可通过 PM2 或 Kubernetes 轻松配置。 \n
- - 如果新代码包含严重错误,“坏”实例可能会处理一些请求。 \n
- - 需要谨慎管理状态(数据库、缓存)。 \n
策略 2:蓝绿部署——无风险的双环境
\n\n
博客
书籍推荐
推荐阅读