Nodejs pm2 有点坑?

Nodejs pm2 有点坑?

centos 中有3个项目,用pm2启动3个项目。用pm2 list 一看,状态全是启动的。 但是其中有一个访问不了,一直报502(我设置二级域名)。之前一直怀疑是nginx配置的问题,后面又去排查端口。 结果再进程中一看,居然只有其中的2个端口,那么第三个端口呢,怀疑端口冲突,改了好几个。还是无果。 最终试了试npm 启动 ,正常启动。nginx也正常映射,网站也能正常访问了。

不知道有没有大神知道这是怎么回事呢? 最终的原因找到了。 Express 4.x 默认将启动模块分离到了./bin/www中,直接使用 supervisor 无法正常监控应用,使得开发过程中的调试非常不方便。 直接在 app.js 添加 app 模块即可。

var debug = require('debug')('my-application'); // debug模块
app.set('port', process.env.PORT || 3000); // 设定监听端口

// Environment sets…

// module.exports = app; 这是 4.x 默认的配置,分离了 app 模块,将它注释即可,上线时可以重新改回来

//启动监听 var server = app.listen(app.get(‘port’), function() { debug('Express server listening on port ’ + server.address().port); }); 之后就可以正常的supervisor app.js进行调试了。 如果需要彻底改变启动方式,还需要修改packages.json

“scripts”: { “start”: “node app.js” // 此处将原本的 ‘node ./bin/www’ 改为 ‘node app.js’ }

之后运行npm start实际就是node app.js了。


6 回复

Nodejs pm2 有点坑?

在CentOS系统中,我管理着三个项目,并使用PM2来启动它们。通过pm2 list命令查看,发现所有项目的状态都是启动的。然而,其中一个项目却无法访问,一直返回502错误(我已经设置了二级域名)。起初,我怀疑是Nginx的配置问题或端口问题。

经过一番排查,我发现进程列表中只显示了两个端口,而第三个端口似乎不见了。我怀疑可能存在端口冲突,尝试更改了多个端口,但问题依旧没有解决。

最终,我决定尝试使用npm start来启动项目。令人惊喜的是,项目成功启动了,Nginx映射也正常工作,网站能够正常访问了。

最终原因找到了

问题的根源在于Express 4.x版本的变化。Express 4.x将启动模块分离到了./bin/www文件中。直接使用PM2无法正常监控这种分离的结构,导致在开发过程中调试变得非常不方便。

解决方案

为了简化调试过程,可以将app.js文件中的启动逻辑重新整合到主文件中。具体步骤如下:

  1. 修改 app.js 文件

    var debug = require('debug')('my-application'); // 引入调试模块
    app.set('port', process.env.PORT || 3000); // 设置监听端口
    
    // 其他环境设置...
    
    // 注释掉默认的模块导出
    // module.exports = app;
    
    // 直接启动监听
    var server = app.listen(app.get('port'), function() {
      debug('Express server listening on port ' + server.address().port);
    });
    
  2. 修改 package.json 文件: 更新启动脚本,使其直接指向修改后的app.js文件。

    "scripts": {
      "start": "node app.js" // 将原本的 'node ./bin/www' 改为 'node app.js'
    }
    

完成上述修改后,可以使用以下命令启动项目:

npm start

这实际上是执行node app.js命令,从而确保PM2能够正确监控并调试项目。

希望这些信息能帮助遇到类似问题的朋友解决问题!


碰见过,不过我用的是kraken + pm2,网上说kraken 跟pm2不兼容,现象跟你的一样。后来google到了解决方法。在入口文件 app.js里,不做启动,把启动放到另外一个类A里,app.js 负责new A 和调用A的方法,即可。有点代理模式的想法。

你的这个问题怎么解决滴 我现在也遇到同样的问题

supervisor 无法正常监控应用 ? 我的可以啊

我也遇到了这种情况, 直接打开bin文件夹,然后Pm2 start www就可以了

根据你的描述,问题主要在于 pm2 启动项目时遇到的一个常见陷阱,即 Express 4.x 的默认配置导致 pm2 不能正确地监控应用的变化。

解释

Express 4.x 中,默认将应用的入口文件放在 ./bin/www,而不是传统的 app.js。这使得使用 pm2 启动应用时,它可能无法正确检测到代码的变化并重启应用。这就是为什么你在使用 pm2 时,虽然所有项目显示为启动状态,但其中一个项目却无法正常访问。

解决方法

  1. 调整入口文件

    • 如果你想使用 pm2 并且想要方便地进行调试,可以将 app.js 作为入口文件,并移除 ./bin/www 的引用。你需要注释掉 module.exports,并将启动逻辑移到 app.js 中。
  2. 更新 package.json

    • 修改 package.json 文件中的 start 脚本,使其指向新的入口文件。

示例代码

app.js

var express = require('express');
var path = require('path');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var index = require('./routes/index');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', index);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handler
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: err
  });
});

var debug = require('debug')('my-application');
app.set('port', process.env.PORT || 3000);

// 启动监听
var server = app.listen(app.get('port'), function() {
  debug('Express server listening on port ' + server.address().port);
});

module.exports = app;  // 保留此行,以便在生产环境中使用

package.json

{
  "name": "your-app",
  "version": "1.0.0",
  "main": "app.js",
  "scripts": {
    "start": "node app.js"
  },
  "dependencies": {
    "express": "^4.17.1"
  }
}

通过这些更改,你可以使用 pm2 更加方便地管理你的 Node.js 应用。希望这能解决你的问题!

回到顶部