简体   繁体   English

使用nvm和pm2运行旧版node.js应用程序时出错

[英]Error running legacy node.js app with nvm and pm2

My Problem 我的问题

I have an old nodejs app (runs under v0.8.18 !) that I'd like to keep running for historical reasons. 我有一个旧的 nodejs应用程序(在v0.8.18v0.8.18 !),出于历史原因,我想继续运行。 I can run it normally from the command line (ie $ node app ), but I can't run it via pm2 (ie $ pm2 start app ). 我可以从命令行(即$ node app )正常运行它,但不能通过pm2(即$ pm2 start app )运行它。

Here's my setup: 这是我的设置:

  • Ubuntu 16.04 Ubuntu 16.04
  • Using nvm 使用nvm
    • node v0.8.18 installed for running the legacy app 安装了用于运行旧版应用程序的节点v0.8.18
    • node v9.3.0 latest stable version with pm2 installed globally 节点v9.3.0与最新的稳定版本pm2全球的装机量
  • App is reverse proxied through nginx (roughly following these instructions ) 通过nginx对应用进行反向代理(大致遵循以下说明
  • I have a config file pm2.json in the root folder of the app created following this thread that looks as follows: 我在此线程之后创建的应用程序的根文件夹中有一个配置文件pm2.json ,如下所示:
[{
  "name": "my-old-app",
  "exec_interpreter": "node@0.8.18",
  "script": "app.js",
  "error": "error.log"
}]
  • Starting pm2 with: 从pm2开始:
$ NVM_DIR=/home/myusername/.nvm/ pm2 start pm2.json

yields: 产量:

$ 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

When I start try to start the app this way, here is the result of running pm2 show my-old-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                                              │
└───────────────────┴──────────────────────────────────────────────────┘

Furthermore, the error that shows up repeatedly in error-0.log is: 此外,在error-0.log反复出现的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)

I don't know why this doesn't work. 我不知道为什么这行不通。

What DOES Work 有什么用

If I just run the app normally from the command line, it works perfectly as expected, ie 如果我只是从命令行正常运行应用程序,则它可以按预期正常运行,即

$ 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

It gets reverse proxied through nginx and is available in a browser via https://old.example.com . 它可以通过nginx反向代理,并且可以通过https://old.example.com在浏览器中使用。 FYI, the contents of my nginx site config: 仅供参考,我的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;
  }
}

Clearly, I can't just use this setup because if the process is interrupted for any reason, it won't get restarted. 显然,我不能仅使用此设置,因为如果该进程由于某种原因被中断,则不会重新启动。 Any ideas? 有任何想法吗? I tried just running the app with node v9.3.0 but the code is too old. 我尝试仅在节点v9.3.0运行应用程序,但是代码太旧了。 It's also too extensive to just re-write in more up-to-date form. 它也太广泛了,无法以最新形式重写。

From the error log, it seems you are trying to run the app using node v9.3.0 . 从错误日志中,您似乎正在尝试使用节点v9.3.0运行该应用程序。

modify your command into something like this [ not tested ] 将您的命令修改为类似以下内容[未测试]

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

I figured it out. 我想到了。 pm2 depends upon pmx , which in turn uses the setTimeout().unref() function . pm2取决于pmx ,这反过来使用setTimeout().unref()函数 The unref() function was not added to nodejs until v0.9.1 . 直到v0.9.1才将unref()函数添加到v0.9.1 Since I was trying to run my app with node v0.8.18 , the unref() function was undefined hence the Object #<Object> has no method 'unref' error message. 由于我尝试使用节点v0.8.18运行我的应用程序,因此unref()函数未定义,因此Object #<Object> has no method 'unref'错误消息。

Trying to run my app under newer node versions always failed, but eventually I realized it was always failing because of the same package: bcrypt . 尝试在较新的节点版本下运行我的应用程序始终会失败,但是最终我意识到,由于使用了相同的软件包bcrypt它始终会失败。 It turns out the original authors of this package had used a weird, buggy, in-between version of bcrypt ( v0.7.5 ). 事实证明,这个软件包的原始作者使用了一个奇怪的,有错误的,中间版本的bcryptv0.7.5 )。 When I switched it up to a slightly newer bcrypt ( v0.7.6 ), I was able to run the entire app with node v0.9.12 , which in turn, made it safe for pm2 to use unref() . 当我切换它到一个稍微新bcryptv0.7.6 ),我是能够与节点运行整个应用程序v0.9.12 ,这反过来又使得它的安全为pm2使用unref()

In Summary... 综上所述...

  1. Don't try to use pm2 to try to run node apps <v0.9.1 , or 不要试图用pm2来尝试运行节点应用<v0.9.1 ,或
  2. If you do, you'll likely need to modify the app so that it can be run with node >=v0.9.1 如果这样做,则可能需要修改应用程序,以便可以在节点>=v0.9.1运行它。

Update 更新资料

One of the maintainers of pm2 let me know that they don't officially support any versions of nodejs <v0.12 and soon they'll be dropping support for that as well . 其中一个维护者的pm2让我知道他们不正式支持的的NodeJS任何版本<v0.12为他们很快就会下探支持,以及

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM