You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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配置:
    {
      "apps": [
        {
          "script": "你的启动入口.js",
          "instances": "max",
          "exec_mode": "cluster",
          "port": 3000 // 指定主端口,PM2内部负责请求分发
        }
      ]
    }
    
    这种情况下,子进程不用单独绑定端口,你直接访问3000端口就能正常用,Nginx也可以直接反向代理到3000端口,省了不少事。

内容的提问来源于stack exchange,提问作者Gaurav Sobti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:25:32