Nodejs 为什么 forever 执行 node 会开两个进程?

Nodejs 为什么 forever 执行 node 会开两个进程?

我使用forever start app.js 查看背景pid进程 发现他一定会启动两个 造成address in use 的错误一直触发

但是直接使用node app.js就正常 请问是什么原因呢? 谢谢

7 回复

在Node.js中,使用forever命令启动应用时可能会遇到启动两个进程的情况,这通常与forever的工作机制有关。forever是一个用于确保Node.js应用程序持续运行的工具,它通过监控你的应用并自动重启它来实现这一点。当使用forever start app.js启动应用时,它实际上会创建一个父进程来管理你的应用,并在子进程中运行你的Node.js应用。

原因分析

  1. 父进程与子进程:当你使用forever start app.js时,forever会在后台启动一个父进程来监控你的应用。这个父进程负责重启你的应用,如果应用崩溃或由于某些原因退出。而你的Node.js应用则在一个独立的子进程中运行。

  2. 端口冲突:如果你的应用试图监听同一个端口(例如8080),而这个端口已经被占用,那么你可能会遇到EADDRINUSE: address already in use错误。这是因为forever尝试启动新的子进程来运行你的应用,但发现该端口已经被另一个进程(可能是之前的一个子进程)占用。

示例代码

假设你的app.js文件如下:

const http = require('http');

const hostname = '127.0.0.1';
const port = 8080;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World\n');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

解决方案

要解决这个问题,你可以确保每次启动新进程前,先停止所有已存在的进程。你可以通过以下步骤来实现:

  1. 停止所有现有的forever进程

    forever stopall
    
  2. 重新启动应用

    forever start app.js
    

这样可以确保没有其他进程占用相同的端口,避免了address already in use错误的发生。

结论

使用forever时出现两个进程的原因主要在于forever为了保证应用的持续运行,会在后台启动一个父进程来监控和管理你的Node.js应用。如果你的应用试图绑定到一个已经被占用的端口,就会导致端口冲突。通过确保每次启动前停止所有现有进程,可以有效避免这类问题。


我理解的是forever要起一个进程来监控的嘛

那请问port占用该怎么处理比较优雅 目前我是直接忽略

这个port不会被占用吧,不过我貌似也遇到这个错误,是在启动的时候服务直接挂掉吧,当时我日志没有仔细看,不知道是不是和你遇到的原因一样 你的forever用的是哪个路径下的?

对 启动就会报EADDRINUSE错误 forever安装之后 就放在自订的路径下 应该跟路径无关吧?

哦,那应该和我的问题一样,我第一次也是在项目路径下的forever启的,然后报这个错了,后面改到/usr/local/lib/node_modules/forever 这个路径,没问题,你试试

当你使用 forever 启动一个 Node.js 应用时,它会在后台管理该应用,并且默认情况下会配置为重启应用。这种行为可能会导致你看到多个进程。然而,在标准情况下,forever 通常不会无故地开启两个进程。

原因分析

  1. 端口占用问题:如果你看到的是“address in use”的错误,这可能意味着你的应用尝试绑定到同一个端口两次。

  2. Forever 配置forever 可以配置为启动多个实例。如果配置了 -m 参数(即最大重启次数),或者通过配置文件设置了多实例,那么 forever 就会启动多个实例。

  3. 应用内部逻辑:你的 app.js 文件中是否有逻辑使得应用在启动后创建了新的子进程?

示例代码及调试方法

示例代码

// app.js
const http = require('http');

http.createServer((req, res) => {
    res.writeHead(200);
    res.end('Hello World\n');
}).listen(3000);

console.log('Server running at http://localhost:3000/');

调试步骤

  1. 检查 Forever 配置

    • 使用 forever list 查看当前运行的 forever 实例。
    • 确认没有多个实例同时运行。
  2. 修改应用代码

    • app.js 中添加日志记录,确认应用是否确实启动了一次。
    console.log(`App started at ${new Date().toISOString()}`);
    
  3. 检查端口绑定

    • 如果你怀疑是端口冲突,可以尝试更换监听端口,或确保没有其他服务占用了相同端口。
    .listen(3001); // 更改端口号
    

总结

如果你仍然遇到两个进程的问题,可能是由于 forever 的配置或应用内部逻辑问题。通过上述步骤逐步排查,应该能帮助你定位问题所在。

回到顶部