PM2 v4.4.0搭配NodeJS v10.16.0集群模式启动报错求助
问题根因
这个错误的本质是PM2在cluster模式下发生了路径错配:把Node.js本身的二进制可执行文件,当成了需要被Node解析的JS脚本文件传入了模块加载器。
两个环境的报错完全对应这个逻辑:
- Windows环境下报错提到读到文件开头的
MZ字符,这是PE格式可执行文件(也就是node.exe)的固定文件头标识 - Ubuntu环境下报错提到读到文件开头的
ELF字符,这是Linux系统可执行文件(也就是NVM安装的node二进制)的固定文件头标识
之所以fork模式运行完全正常、切换到cluster模式就报错,是因为两种模式的启动逻辑差异:
- fork模式下PM2直接通过系统spawn接口拼接启动命令:固定将Node可执行文件作为启动入口,你配置的
script值作为参数传给Node执行,不做额外的路径解析校验;如果script指向的是无后缀的可执行启动脚本,fork模式也可以通过设置exec_interpreter: "none"直接调用脚本启动 - cluster模式下PM2会通过内置的模块解析逻辑做路径校验匹配,且cluster模式依赖Node内置的集群调度能力,不支持直接运行非Node入口的可执行文件。当你的配置里
script字段只写了无后缀的相对文件名server、没有明确指向真实的JS脚本路径时,就会在路径解析过程中发生混淆,把本该作为启动入口的Node二进制路径错当成待加载的脚本,传入Node的模块编译器,最终触发Invalid or unexpected token的二进制内容解析错误。
注:你给出的配置样例里本身存在JSON语法漏写:"wait_ready": true行末尾缺失英文逗号,虽然不直接触发当前报错,但可能加剧路径解析的异常。
解决步骤
- 修正
script字段的写法:不要只写无后缀的相对文件名,要明确指向真实的JS服务入口文件,比如如果入口是当前目录下的服务启动文件,就写为"./server.js",确保Node能直接通过这个路径定位到JS代码文件,不存在路径歧义 - 显式指定Node执行路径:在配置里增加
exec_interpreter字段,填写当前环境下Node可执行文件的绝对路径,不让PM2自行从PATH环境变量中检索Node位置:- Windows Server 2012环境示例:
"exec_interpreter": "C:\\Program Files\\nodejs\\node.exe" - Ubuntu 18 + NVM环境示例:
"exec_interpreter": "/opt/nvm/nvm/versions/node/v10.16.0/bin/node"
- Windows Server 2012环境示例:
- 补全JSON配置的语法错误:在
"wait_ready": true行末尾补上缺失的英文逗号,保证配置文件能被无异常解析 - 启动前做手动验证:在PM2启动前,先在配置文件所在的工作目录手动执行
node [你配置的script路径],确认服务能正常启动、没有路径找不到的问题,再使用pm2 start切换为cluster模式启动 - 不需要调整的参数:配置里的
instances:0是PM2的合法参数(代表实例数匹配机器CPU核心数)、wait_ready/listen_timeout/kill_timeout等超时配置也和当前报错无关,不需要修改参数值。
内容的提问来源于stack exchange,提问作者Hamber
相关产品推荐
相关产品推荐

