阿里云主机折上折
  • 微信号
您当前的位置:网站首页 > 进程管理工具

进程管理工具

作者:陈川 阅读数:43772人阅读 分类: Node.js

进程管理工具的必要性

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"]

性能优化技巧

  1. 根据CPU核心数合理设置进程数:
const numCPUs = require('os').cpus().length;
const workers = Math.min(numCPUs, 4); // 不超过4个进程
  1. 内存限制:
pm2 start app.js --max-memory-restart 500M
  1. 使用exec_mode的cluster模式:
module.exports = {
  apps: [{
    exec_mode: 'cluster',
    instances: 'max'
  }]
};

安全注意事项

  1. 不要以root用户运行Node.js进程
  2. 限制进程权限:
pm2 start app.js --uid www-data --gid www-data
  1. 定期更新PM2版本
  2. 保护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

上一篇:进程间通信

下一篇:多核CPU利用

前端川

前端川,陈川的代码茶馆🍵,专治各种不服的Bug退散符💻,日常贩卖秃头警告级的开发心得🛠️,附赠一行代码笑十年的摸鱼宝典🐟,偶尔掉落咖啡杯里泡开的像素级浪漫☕。‌