如何用PM2启动对应CPU核心数的Node.js进程并通过Nginx负载均衡
解决思路与落地配置
1. PM2 启动配置(不启用集群负载均衡)
核心逻辑是指定PM2使用fork模式启动进程,而非默认的cluster集群模式,同时根据CPU核心数动态生成对应数量的独立进程,每个进程监听不同端口。
首先在你的Node.js项目根目录新建PM2配置文件ecosystem.config.js,内容如下:
const os = require('os'); const CPU_CORE_COUNT = os.cpus().length; const BASE_PORT = 3000; // 可自行修改为你想用的起始端口 module.exports = { apps: [{ name: 'node-service', script: './app.js', // 替换为你的Node.js入口文件路径 exec_mode: 'fork', // 关键:禁用cluster集群模式,使用独立fork进程 instances: CPU_CORE_COUNT, // 进程数和CPU核心数保持一致 instance_var: 'PM2_INSTANCE_ID', // 注入实例序号环境变量 env: { // 每个实例的端口 = 基础端口 + 实例序号,确保不冲突 NODE_PORT: BASE_PORT + parseInt(process.env.PM2_INSTANCE_ID || 0) } }] }
然后在你的Node.js代码中,监听端口从process.env.NODE_PORT读取即可,示例:
const port = process.env.NODE_PORT || 3000; app.listen(port, () => { console.log(`服务运行在端口 ${port}`); });
启动命令:pm2 start ecosystem.config.js
如果后续CPU核心数变动,执行pm2 reload ecosystem.config.js即可自动调整进程数量和对应端口。
2. Nginx 配置自动适配方案
核心思路是通过脚本自动生成对应进程端口的上游服务配置,无需手动修改Nginx配置文件,实现平滑适配。
前置配置
首先修改Nginx主配置(通常路径为/etc/nginx/nginx.conf),在http块中添加如下配置,预留动态生成的上游配置引入路径:
http { # 其他原有配置保持不变 include /etc/nginx/conf.d/node_upstream.conf; # 新增这一行 server { listen 80; server_name your-domain.com; # 替换为你的实际域名 location / { proxy_pass http://node_backend; # 其他proxy相关配置(如proxy_set_header等)保持不变 } } }
自动生成配置脚本
新建脚本文件/opt/update_nginx_upstream.sh,内容如下:
#!/bin/bash # 读取当前CPU核心数,和PM2进程数保持一致 CPU_CORE_COUNT=$(nproc) BASE_PORT=3000 # 和PM2配置中的基础端口保持一致 UPSTREAM_CONF_PATH="/etc/nginx/conf.d/node_upstream.conf" # 生成upstream配置内容 echo "upstream node_backend {" > $UPSTREAM_CONF_PATH for ((i=0; i<CPU_CORE_COUNT; i++)) do echo " server 127.0.0.1:$((BASE_PORT + i));" >> $UPSTREAM_CONF_PATH done echo "}" >> $UPSTREAM_CONF_PATH # 校验Nginx配置合法性,合法则重载 if nginx -t; then nginx -s reload echo "Nginx配置已更新并重载成功" else echo "Nginx配置校验失败,已回滚" rm -f $UPSTREAM_CONF_PATH fi
给脚本加执行权限:chmod +x /opt/update_nginx_upstream.sh
触发脚本的常用方式
- 手动触发:CPU核心数调整后,先执行
pm2 reload ecosystem.config.js,再执行/opt/update_nginx_upstream.sh即可 - 自动触发:可以将脚本加入PM2的启动后钩子,或者添加定时任务(如每分钟执行一次),实现无感知适配。
内容的提问来源于stack exchange,提问作者Константин Ван
相关产品推荐
相关产品推荐

