【问题标题】:Error running legacy node.js app with nvm and pm2使用 nvm 和 pm2 运行遗留 node.js 应用程序时出错
【发布时间】:2018-01-05 03:57:31
【问题描述】:

我的问题

我有一个 nodejs 应用程序(在v0.8.18 下运行!),出于历史原因,我想继续运行它。我可以从命令行正常运行它(即$ node app),但我不能通过pm2运行它(即$ pm2 start app)。

这是我的设置:

  • Ubuntu 16.04
  • 使用nvm
    • 为运行旧版应用程序安装了节点v0.8.18
    • node v9.3.0 最新稳定版本,全局安装pm2
  • 应用通过 nginx 反向代理(大致遵循these instructions
  • 我在创建的应用程序的根文件夹pm2.json 中有一个配置文件following this thread,如下所示:
[{
  "name": "my-old-app",
  "exec_interpreter": "node@0.8.18",
  "script": "app.js",
  "error": "error.log"
}]
  • 开始 pm2:
$ NVM_DIR=/home/myusername/.nvm/ pm2 start pm2.json

产量:

$ NVM_DIR=/home/myusername/.nvm/ pm2 start pm2.json
[PM2][WARN] Applications my-old-app not running, starting...
[PM2] Setting Node to v0.8.18 (path=/home/myusername/.nvm/v0.8.18/bin/node)
[PM2] App [my-old-app] launched (1 instances)
┌─────────────────┬────┬──────┬──────┬────────┬─────────┬────────┬─────┬──────────┬────────────┬──────────┐
│ App name        │ id │ mode │ pid  │ status │ restart │ uptime │ cpu │ mem      │ user       │ watching │
├─────────────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────┼──────────┼────────────┼──────────┤
│ my-old-app      │ 0  │ fork │ 5879 │ online │ 0       │ 0s     │ 0%  │ 7.9 MB   │ myusername │ disabled │
└─────────────────┴────┴──────┴──────┴────────┴─────────┴────────┴─────┴──────────┴────────────┴──────────┘
 Use `pm2 show <id|name>` to get more details about an app

当我开始尝试以这种方式启动应用程序时,这是运行pm2 show my-old-app的结果

 Describing process with id 0 - name my-old-app
┌───────────────────┬──────────────────────────────────────────────────┐
│ status            │ errored                                          │
│ name              │ my-old-app                                       │
│ restarts          │ 15                                               │
│ uptime            │ 0                                                │
│ script path       │ /home/myusername/my-old-app/app.js               │
│ script args       │ N/A                                              │
│ error log path    │ /home/myusername/my-old-app/error-0.log          │
│ out log path      │ /home/myusername/.pm2/logs/my-old-app-out-0.log  │
│ pid path          │ /home/myusername/.pm2/pids/my-old-app-0.pid      │
│ interpreter       │ /home/myusername/.nvm/v0.8.18/bin/node           │
│ interpreter args  │ N/A                                              │
│ script id         │ 0                                                │
│ exec cwd          │ /home/myusername/my-old-app/                     │
│ exec mode         │ fork_mode                                        │
│ node.js version   │ N/A                                              │
│ watch & reload    │ ✘                                                │
│ unstable restarts │ 0                                                │
│ created at        │ N/A                                              │
└───────────────────┴──────────────────────────────────────────────────┘

此外,error-0.log 中反复出现的错误是:

domain.js:66
    throw er;
          ^
TypeError: Object #<Object> has no method 'unref'
    at Object.PMX.init (/home/myusername/.nvm/versions/node/v9.3.0/lib/node_modules/pm2/node_modules/pmx/lib/pmx.js:81:8)
    at Object.<anonymous> (/home/myusername/.nvm/versions/node/v9.3.0/lib/node_modules/pm2/lib/ProcessContainerFork.js:8:18)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.runMain (module.js:492:10)
    at process.startup.processNextTick.process._tickCallback (node.js:244:9)

我不知道为什么这不起作用。

什么工作

如果我只是从命令行正常运行应用程序,它会按预期完美运行,即

$ nvm use 0.8.18
Now using node v0.8.18 (npm v1.2.2)
$ node app
   info  - socket.io started
Express server listening on port 37426

它通过 nginx 进行反向代理,并可通过https://old.example.com 在浏览器中使用。仅供参考,我的 nginx 站点配置的内容:

server {
  listen 80;
  listen [::]:80;
  listen 443 ssl;
  ssl_certificate /etc/letsencrypt/live/old.example.com/fullchain.pem; # managed by Certbot
  ssl_certificate_key /etc/letsencrypt/live/old.example.com/privkey.pem; # managed by Certbot
  include /etc/letsencrypt/options-ssl-nginx.conf;

  server_name old.example.com;

  if ($scheme != "https") {
    return 301 https://$host$request_uri;
  }

  # Pass requests for / to localhost:37426:
  location / {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-NginX-Proxy true;
    proxy_pass http://localhost:37426/;
    proxy_ssl_session_reuse off;
    proxy_set_header Host $http_host;
    proxy_cache_bypass $http_upgrade;
    proxy_redirect off;
  }
}

显然,我不能只使用此设置,因为如果进程因任何原因中断,它不会重新启动。有任何想法吗?我尝试使用节点v9.3.0 运行应用程序,但代码太旧了。它也过于广泛,无法以更新的形式重新编写。

【问题讨论】:

  • 奇怪的是,无论是在我的应用程序中还是在全局安装的包中,我都找不到名为 domain.jsany 文件。

标签: node.js nginx pm2 nvm


【解决方案1】:

从错误日志中,您似乎正在尝试使用节点 v9.3.0 运行应用程序。

将你的命令修改成这样的[未测试]

NVM_DIR=/home/myusername/.nvm/ nvm use 0.8.18 &amp;&amp; pm2 start pm2.json

【讨论】:

  • 可以肯定的是,我 am 运行 pm2v9.3.0 但正如您从我刚刚添加的输出中看到的那样,该应用程序肯定是以 @987654325 启动的@。不过,按照您的建议,我在v0.8.18(即nvm use 0.8.18 &amp;&amp; npm i -g pm2)下安装了pm2,但没有任何区别
  • 哦!实际上我读错了输出。在v0.8.18 下安装pm2 失败。 1pm2` 似乎想要node &gt;= 0.12。所以我尝试了nvm install 0.12.18 &amp;&amp; npm i -g pm2,然后尝试运行应用程序(node app)失败。删除node_modules 并尝试在v0.12.18 下重新安装。仍然没有工作。 bcrypt 的版本太旧,无法使用 v0.12.18
【解决方案2】:

我想通了。 pm2 depends upon pmx,而后者又使用setTimeout().unref() functionunref() 函数直到 v0.9.1 才添加到 nodejs。由于我尝试使用节点 v0.8.18 运行我的应用程序,因此 unref() 函数未定义,因此出现 Object #&lt;Object&gt; has no method 'unref' 错误消息。

尝试在较新的节点版本下运行我的应用程序总是失败,但最终我意识到它总是因为同一个包而失败:bcrypt。事实证明,这个包的原始作者使用了一个奇怪的、有缺陷的、介于两者之间的 bcrypt (v0.7.5) 版本。当我将它切换到稍新的bcrypt (v0.7.6) 时,我能够使用节点v0.9.12 运行整个应用程序,这反过来又使pm2 可以安全地使用unref()

总结...

  1. 不要尝试使用pm2 来尝试运行节点应用&lt;v0.9.1,或者
  2. 如果这样做,您可能需要修改应用程序,以便它可以使用节点 &gt;=v0.9.1 运行

更新

pm2 的维护者之一告诉我they don't officially support any versions of nodejs &lt;v0.12 and soon they'll be dropping support for that as well

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-20
    • 2016-06-11
    • 2012-07-20
    • 1970-01-01
    • 2018-08-26
    • 1970-01-01
    • 2019-10-27
    相关资源
    最近更新 更多