Node.js 进程管理与监控
进程管理确保应用稳定、高效运行。
进程守护
PM2 进程管理器
Bash
# 安装
npm install -g pm2
# 启动应用
pm2 start app.js
# 启动配置
pm2 start ecosystem.config.js
# 常用命令
pm2 list # 查看进程列表
pm2 logs # 查看日志
pm2 restart all # 重启所有
pm2 stop all # 停止所有
pm2 delete all # 删除所有
pm2 monit # 监控界面
PM2 配置文件
JavaScript
// ecosystem.config.js
module.exports = {
apps: [
{
name: 'my-app',
script: 'app.js',
instances: 'max', // CPU 核数
exec_mode: 'cluster', // 集群模式
autorestart: true, // 自动重启
watch: false, // 文件监控
max_memory_restart: '500M', // 内存限制
env: {
NODE_ENV: 'production',
PORT: 3000
},
env_development: {
NODE_ENV: 'development',
PORT: 3001
},
error_file: './logs/error.log',
out_file: './logs/out.log',
log_date_format: 'YYYY-MM-DD HH:mm:ss'
}
]
};
自动重启策略
异常自动重启
JavaScript
// cluster 自动重启
const cluster = require('cluster');
if (cluster.isMaster) {
cluster.on('exit', (worker, code) => {
if (code !== 0) {
console.log(`Worker 异常退出,重启中...`);
setTimeout(() => cluster.fork(), 1000);
}
});
}
内存限制重启
JavaScript
// 监控内存使用
setInterval(() => {
const used = process.memoryUsage();
const rssMB = used.rss / 1024 / 1024;
if (rssMB > 500) {
console.log('内存超限,准备退出');
process.exit(1); // PM2 自动重启
}
}, 30000);
优雅关闭
处理退出信号
JavaScript
const server = require('http').createServer();
// 优雅关闭
function gracefulShutdown() {
console.log('正在关闭...');
// 停止接收新连接
server.close(() => {
console.log('服务器已关闭');
// 清理资源
cleanupResources();
process.exit(0);
});
// 强制退出超时
setTimeout(() => {
console.log('强制退出');
process.exit(1);
}, 10000);
}
// 监听信号
process.on('SIGTERM', gracefulShutdown);
process.on('SIGINT', gracefulShutdown);
连接处理
JavaScript
const connections = new Set();
server.on('connection', (conn) => {
connections.add(conn);
conn.on('close', () => connections.delete(conn));
});
function gracefulShutdown() {
server.close();
// 关闭所有连接
connections.forEach(conn => conn.end());
// 等待连接关闭
let count = 0;
const checkInterval = setInterval(() => {
if (connections.size === 0 || count++ > 10) {
clearInterval(checkInterval);
process.exit(0);
}
}, 1000);
}
资源监控
内存监控
JavaScript
// 获取内存使用
const used = process.memoryUsage();
console.log({
rss: `${used.rss / 1024 / 1024} MB`, // 总内存
heapTotal: `${used.heapTotal / 1024 / 1024} MB`,
heapUsed: `${used.heapUsed / 1024 / 1024} MB`,
external: `${used.external / 1024 / 1024} MB`
});
// 定期监控
setInterval(() => {
const used = process.memoryUsage();
console.log(`堆内存使用: ${used.heapUsed / 1024 / 1024} MB`);
}, 10000);
CPU 监控
JavaScript
// CPU 使用统计
const startUsage = process.cpuUsage();
setTimeout(() => {
const usage = process.cpuUsage(startUsage);
console.log({
user: `${usage.user / 1000} ms`,
system: `${usage.system / 1000} ms`
});
}, 1000);
使用 os 模块
JavaScript
const os = require('os');
console.log({
cpuCount: os.cpus().length,
freeMem: `${os.freemem() / 1024 / 1024 / 1024} GB`,
totalMem: `${os.totalmem() / 1024 / 1024 / 1024} GB`,
loadAvg: os.loadavg() // [1分钟, 5分钟, 15分钟]
});
健康检查
HTTP 健康检查
JavaScript
const express = require('express');
const app = express();
app.get('/health', (req, res) => {
const health = {
uptime: process.uptime(),
memory: process.memoryUsage(),
timestamp: Date.now(),
status: 'ok'
};
res.json(health);
});
app.get('/ready', (req, res) => {
// 检查依赖服务
if (isReady()) {
res.json({ status: 'ready' });
} else {
res.status(503).json({ status: 'not ready' });
}
});
进程状态输出
JavaScript
// 输出进程信息
process.title = 'my-app-worker'; // 设置进程名
console.log({
pid: process.pid,
title: process.title,
uptime: process.uptime(),
argv: process.argv,
execPath: process.execPath,
cwd: process.cwd()
});
日志管理
Winston 日志
JavaScript
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
transports: [
new winston.transports.File({ filename: 'error.log', level: 'error' }),
new winston.transports.File({ filename: 'combined.log' })
]
});
// 错误日志记录
process.on('uncaughtException', (err) => {
logger.error('未捕获异常', { error: err.stack });
process.exit(1);
});
process.on('unhandledRejection', (reason) => {
logger.error('未处理 Promise 拒绝', { reason });
});
注意事项
- 生产环境必须使用进程守护(PM2)
- 优雅关闭等待处理完成,避免数据丢失
- 内存监控设置合理阈值
- 健康检查接口供负载均衡使用
- 记录异常日志便于排查
要点总结
- PM2 实现进程守护和自动重启
process.on('SIGTERM')处理优雅关闭process.memoryUsage()监控内存- 健康检查接口供外部监控
- 记录异常日志,自动重启恢复
📝 发现内容有误?点击此处直接编辑