服务自动化运维
项目开发完成后,如何高效、可靠地将其部署到生产环境,是保障服务质量的关键。本章将探讨如何利用 npm script 实现服务运维自动化,涵盖版本管理、服务部署、进程与日志管理等核心环节。
了解这些非前端的知识,能让你具备更全面的大局观,从容应对从开发到交付的全过程。
1. 自动化版本管理
规范的版本管理是项目迭代的基础。npm version 命令为我们提供了强大的支持。
遵循 SemVer 规范
我们推荐使用 Semantic Versioning (SemVer) 规范。你可以通过以下脚本轻松管理版本,并自动推送到 Git 仓库:
"scripts": {
"release:patch": "npm version patch && git push && git push --tags",
"release:minor": "npm version minor && git push && git push --tags",
"release:major": "npm version major && git push && git push --tags"
}npm run release:patch:发布修订版(例如1.0.0->1.0.1)。npm run release:minor:发布次版本(例如1.0.1->1.1.0)。npm run release:major:发布主版本(例如1.1.0->2.0.0)。
自定义版本规则
如果项目有特殊的版本需求(例如版本号不超过 10),你可以编写自定义脚本。以下是一个示例,它会在补丁版本达到 9 时自动提升次版本:
在 scripts/bump.sh 中添加(确保文件有可执行权限 chmod a+x):
#!/usr/bin/env bash
version=$(cat package.json | grep version | awk -F\" '{print $4}')
components=($(echo $version | tr '.' '\n'))
major=${components[0]}
minor=${components[1]}
patch=${components[2]}
release='patch'
if [ $patch -ge 9 ]; then
if [ $minor -ge 9 ]; then
release='major'
else
release='minor'
fi
fi
npm run release:$release在 package.json 中配置 bump 命令:
"scripts": {
"bump": "scripty"
}注意:自定义版本规则可能会破坏 SemVer 的通用约定,请谨慎使用。
2. 服务部署与管理
我们将使用 pm2——一个功能强大的 Node.js 进程管理器,来实现服务的稳定运行和高效管理。
设置 Express 服务器
首先,我们需要一个简单的 HTTP 服务器来托管我们的应用。我们使用 express 提供服务,并用 morgan 记录访问日志。
安装依赖:
npm install express morgan --save-dev创建 server.js:
const express = require("express")
const morgan = require("morgan")
const app = express()
const port = process.env.PORT || 8080
app.use(express.static("./dist"))
app.use(morgan("combined"))
app.listen(port, (err) => {
if (err) {
console.error("Server start error:", err)
process.exit(1)
}
console.log(`Server started at port ${port}`)
})使用 PM2 进行进程管理
pm2 提供了进程守护、负载均衡、日志管理等丰富功能。
安装 pm2:
npm install pm2 --save-dev创建 pm2.json 配置文件,以声明方式管理服务:
{
"apps": [
{
"name": "npm-script-workflow",
"script": "./server.js",
"out_file": "./logs/stdout.log",
"error_file": "./logs/stderr.log",
"log_date_format": "YYYY-MM-DD HH:mm:ss",
"instances": 0,
"exec_mode": "cluster",
"max_memory_restart": "800M",
"merge_logs": true,
"env": {
"NODE_ENV": "production",
"PORT": 8080
}
}
]
}配置解析:
instances: 0:pm2会根据 CPU 核数自动创建相应数量的进程。exec_mode: "cluster":开启集群模式,实现负载均衡。env:为生产环境注入环境变量。
配置部署脚本
我们将部署流程封装在 npm script 中,实现一键部署。
"scripts": {
"predeploy": "npm install && npm run build",
"deploy": "pm2 restart pm2.json"
}predeploy:在部署前自动安装依赖并执行构建。deploy:使用pm2重启服务,应用最新代码。
现在,只需运行 npm run deploy 即可完成整个部署过程。
日志管理
虽然 pm2 logs 可以查看日志,但当服务器上运行多个服务时,日志会混合在一起。我们建议为当前项目配置专用的日志查看命令。
首先,创建日志目录并将其添加到 .gitignore:
mkdir logs
touch logs/.gitkeep.gitignore:
dist
logs然后,在 package.json 中添加 logs 脚本:
"scripts": {
"logs": "tail -f logs/*"
}运行 npm run logs 即可实时查看当前应用的所有日志。
3. 安全与性能考量
- 环境变量:切勿将敏感信息(如 API 密钥、数据库密码)硬编码在代码中。使用
.env文件或系统环境变量,并通过pm2.json的env字段注入。 - 日志轮转:生产环境的日志文件可能会迅速增长。考虑使用
logrotate或pm2-logrotate等工具来管理日志文件的大小和归档。 - 资源限制:在
pm2.json中设置max_memory_restart,以防止内存泄漏导致服务崩溃。
总结与最佳实践
通过本章的学习,你已经掌握了如何利用 npm script 和 pm2 实现自动化、高可用的服务运维流程。
核心要点:
- 版本管理自动化:使用
npm version结合 Git 操作,简化发布流程。 - 声明式进程管理:通过
pm2.json配置文件,确保服务配置的一致性和可复现性。 - 部署流程脚本化:将构建、安装、重启等步骤封装在 npm script 中,实现一键部署。
- 独立的日志管理:为每个项目配置独立的日志查看命令,便于问题排查。
将这些实践应用到你的项目中,将极大提升你的开发与运维效率。
本节用到的代码见 GitHub。建议边看边动手练习,注意切换到正确的分支
13-use-npm-script-for-devops。