进程管理工具
进程管理工具的必要性
Node.js作为单线程运行时环境,在处理CPU密集型任务时容易阻塞事件循环。进程管理工具能够帮助开发者充分利用多核CPU资源,提高应用性能和稳定性。通过进程管理,可以实现应用的自动重启、负载均衡、日志收集等功能。
Node.js内置进程模块
Node.js提供了child_process
模块用于创建和管理子进程。这是最基本的进程管理方式:
const { spawn } = require('child_process');
// 创建子进程执行ls命令
const ls = spawn('ls', ['-lh', '/usr']);
ls.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
ls.stderr.on('data', (data) => {
console.error(`stderr: ${data}`);
});
ls.on('close', (code) => {
console.log(`子进程退出,退出码 ${code}`);
});
cluster
模块允许轻松创建共享服务器端口的子进程:
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log(`主进程 ${process.pid} 正在运行`);
// 衍生工作进程
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`工作进程 ${worker.process.pid} 已退出`);
});
} else {
// 工作进程可以共享任何TCP连接
http.createServer((req, res) => {
res.writeHead(200);
res.end('你好世界\n');
}).listen(8000);
console.log(`工作进程 ${process.pid} 已启动`);
}
PM2进程管理器
PM2是Node.js应用最流行的进程管理器之一,具有丰富的功能:
安装PM2:
npm install pm2 -g
启动应用:
pm2 start app.js
常用命令:
# 列出所有应用
pm2 list
# 监控资源使用情况
pm2 monit
# 查看日志
pm2 logs
# 重启应用
pm2 restart app_name
# 停止应用
pm2 stop app_name
# 删除应用
pm2 delete app_name
PM2配置文件ecosystem.config.js
示例:
module.exports = {
apps: [{
name: 'app',
script: './app.js',
instances: 'max',
autorestart: true,
watch: false,
max_memory_restart: '1G',
env: {
NODE_ENV: 'development'
},
env_production: {
NODE_ENV: 'production'
}
}]
};
Forever工具
Forever是另一个简单的Node.js进程管理工具,适合不需要复杂功能的小型应用:
安装:
npm install forever -g
基本用法:
# 启动应用
forever start app.js
# 停止应用
forever stop app.js
# 列出所有运行中的应用
forever list
# 监控文件变化并自动重启
forever -w app.js
进程管理的高级特性
负载均衡
使用cluster模块或PM2可以轻松实现负载均衡。PM2会自动根据CPU核心数分配进程:
pm2 start app.js -i max
零停机重启
PM2支持reload命令实现零停机重启:
pm2 reload app_name
日志管理
PM2提供集中式日志管理:
# 标准输出和错误日志
pm2 logs
# 日志文件分割
pm2 install pm2-logrotate
监控和告警
PM2可以与Keymetrics.io集成实现实时监控:
pm2 link <secret> <public>
进程间通信
主进程和工作进程之间可以通过IPC通信:
// 主进程
cluster.on('message', (worker, message) => {
console.log(`收到来自工作进程 ${worker.id} 的消息: ${message}`);
});
// 工作进程
process.send({ hello: '来自工作进程的消息' });
错误处理和进程恢复
PM2配置中的错误处理:
module.exports = {
apps: [{
// ...
error_file: '/var/log/node-app/err.log',
out_file: '/var/log/node-app/out.log',
merge_logs: true,
min_uptime: '60s',
max_restarts: 10
}]
};
容器环境中的进程管理
在Docker容器中使用PM2的最佳实践:
FROM node:14
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
# 安装PM2
RUN npm install pm2 -g
# 启动应用
CMD ["pm2-runtime", "ecosystem.config.js"]
性能优化技巧
- 根据CPU核心数合理设置进程数:
const numCPUs = require('os').cpus().length;
const workers = Math.min(numCPUs, 4); // 不超过4个进程
- 内存限制:
pm2 start app.js --max-memory-restart 500M
- 使用exec_mode的cluster模式:
module.exports = {
apps: [{
exec_mode: 'cluster',
instances: 'max'
}]
};
安全注意事项
- 不要以root用户运行Node.js进程
- 限制进程权限:
pm2 start app.js --uid www-data --gid www-data
- 定期更新PM2版本
- 保护PM2的HTTP接口(如果启用)
调试进程管理问题
PM2调试命令:
# 显示详细日志
pm2 logs --lines 200
# 显示进程详情
pm2 show app_name
# 检查PM2状态
pm2 ping
# 生成诊断报告
pm2 report
自定义进程管理方案
对于特殊需求,可以基于child_process模块构建自定义方案:
const { fork } = require('child_process');
const path = require('path');
class ProcessManager {
constructor() {
this.workers = [];
this.maxWorkers = 4;
}
start() {
for (let i = 0; i < this.maxWorkers; i++) {
const worker = fork(path.join(__dirname, 'worker.js'));
this.workers.push(worker);
worker.on('message', (msg) => {
console.log(`Worker ${worker.pid}: ${msg}`);
});
worker.on('exit', (code) => {
console.log(`Worker ${worker.pid} exited with code ${code}`);
this.replaceWorker(worker);
});
}
}
replaceWorker(deadWorker) {
const index = this.workers.indexOf(deadWorker);
if (index !== -1) {
const newWorker = fork(path.join(__dirname, 'worker.js'));
this.workers[index] = newWorker;
console.log(`Replaced worker ${deadWorker.pid} with ${newWorker.pid}`);
}
}
}
const manager = new ProcessManager();
manager.start();
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn