PM2集群模式下Express服务端口配置问题咨询
解决PM2集群模式下端口冲突的问题
我太懂你现在的糟心情况了——PM2按CPU核心数启动一堆进程,结果每个Node服务都死磕3000端口,第一个占了坑之后,剩下的全启动失败。结合你已经在用Nginx反向代理的场景,给你几个实用的解决思路:
1. 让PM2自动分配端口(最省心的方案)
PM2的集群模式本身就支持自动给子进程分配不同端口,你只需要做两处小调整:
- 修改Node服务代码:别再硬写3000端口了,改用PM2提供的环境变量。比如Express/Koa框架可以这么写:
const port = process.env.PORT || 3000; app.listen(port, () => { console.log(`服务跑在端口 ${port} 啦`); }); - 更新PM2配置文件:在你的JSON配置里,指定
exec_mode: "cluster",并通过env设置基础端口,PM2会自动给每个进程分配3000、3001、3002...这类连续端口:
这样每个子进程都有专属端口,再也不会抢端口打架了。{ "apps": [ { "script": "npm", "args": "start", // 记得补充完整启动命令,对应package.json里的启动脚本 "instances": "max", "exec_mode": "cluster", "env": { "PORT": 3000 } } ] }
2. 用命令行参数传递端口(适合不想改代码的情况)
如果不想动服务代码,可以通过PM2的node_args给每个进程传不同的端口参数:
- 调整PM2配置:
{ "apps": [ { "script": "你的启动入口.js", "instances": "max", "exec_mode": "cluster", "node_args": "--port=%PORT%", "env": { "PORT": 3000 } } ] } - 在Node代码里读取参数:
const argv = require('minimist')(process.argv.slice(2)); const port = argv.port || 3000; app.listen(port);
3. 更新Nginx配置,实现多端口负载均衡
当每个PM2进程都有了自己的端口后,你需要修改Nginx配置,让它把请求转发到这些端口,实现负载均衡:
upstream node_cluster { server 127.0.0.1:3000; server 127.0.0.1:3001; server 127.0.0.1:3002; # 按CPU核心数添加对应数量的端口即可 } server { listen 80; server_name your-domain.com; location / { proxy_pass http://node_cluster; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }
要是嫌手动写端口麻烦,也可以给upstream加上least_conn参数,让Nginx自动把请求分配给连接数最少的进程,后续PM2增减进程时,只要端口连续,Nginx配置不用频繁改动。
额外小技巧:用PM2内置的负载均衡
其实PM2集群模式自带负载均衡功能,如果你不需要Nginx做静态资源托管或SSL处理,完全可以让PM2直接监听主端口,它会自动把请求转发到各个子进程:
- 修改PM2配置:
这种情况下,子进程不用单独绑定端口,你直接访问3000端口就能正常用,Nginx也可以直接反向代理到3000端口,省了不少事。{ "apps": [ { "script": "你的启动入口.js", "instances": "max", "exec_mode": "cluster", "port": 3000 // 指定主端口,PM2内部负责请求分发 } ] }
内容的提问来源于stack exchange,提问作者Gaurav Sobti
相关产品推荐
相关产品推荐

