当前位置: 首页 > 面试题库 >

进程被杀死后,如何正常关闭Express Server?

米夕
2023-03-14
问题内容

在生产环境中运行Express应用程序时,我想在服务器进程被杀死(即,发送SIGTERM或SIGINT)时正常关闭服务器。

这是我的代码的简化版本:

const express = require('express');

const app = express();

app.get('/', (req, res) => res.json({ ping: true }));

const server = app.listen(3000, () => console.log('Running…'));

setInterval(() => server.getConnections(
    (err, connections) => console.log(`${connections} connections currently open`)
), 1000);

process.on('SIGTERM', shutDown);
process.on('SIGINT', shutDown);

function shutDown() {
    console.log('Received kill signal, shutting down gracefully');
    server.close(() => {
        console.log('Closed out remaining connections');
        process.exit(0);
    });

    setTimeout(() => {
        console.error('Could not close connections in time, forcefully shutting down');
        process.exit(1);
    }, 10000);
}

当我运行它并在浏览器中调用URL http:// localhost:3000
/
时,setInterval函数中的log语句将一直打印“当前打开1个连接”,直到我真正关闭浏览器窗口为止。显然,即使关闭选项卡也会使连接保持打开状态。

因此,我要通过按Ctrl + C杀死服务器,它将在超时后运行,并在10秒钟后打印“无法关闭连接”,同时继续打印“ 1个连接打开”。

仅当我在终止进程之前关闭浏览器窗口时,才会收到“已关闭剩余的连接”消息。

我在这里想念什么? 正常关闭Express服务器的正确方法是什么?


问题答案:

如果有人感兴趣,我会自己找到解决方案(很想听听评论中的反馈)。

我为服务器上打开的连接添加了一个侦听器,将对这些连接的引用存储在数组中。关闭连接后,将从阵列中将其删除。

当服务器被杀死时,每个连接都通过调用其end方法来关闭。对于某些浏览器(例如Chrome),这还不够,所以在超时后,我会调用destroy每个连接。

const express = require('express');

const app = express();

app.get('/', (req, res) => res.json({ ping: true }));

const server = app.listen(3000, () => console.log('Running…'));

setInterval(() => server.getConnections(
    (err, connections) => console.log(`${connections} connections currently open`)
), 1000);

process.on('SIGTERM', shutDown);
process.on('SIGINT', shutDown);

let connections = [];

server.on('connection', connection => {
    connections.push(connection);
    connection.on('close', () => connections = connections.filter(curr => curr !== connection));
});

function shutDown() {
    console.log('Received kill signal, shutting down gracefully');
    server.close(() => {
        console.log('Closed out remaining connections');
        process.exit(0);
    });

    setTimeout(() => {
        console.error('Could not close connections in time, forcefully shutting down');
        process.exit(1);
    }, 10000);

    connections.forEach(curr => curr.end());
    setTimeout(() => connections.forEach(curr => curr.destroy()), 5000);
}


 类似资料:
  • 问题内容: 我有一个Python应用程序,该应用程序打开一个简单的TCP套接字以与单独主机上的另一个Python应用程序进行通信。有时程序会出错,或者我将直接杀死它,并且无论哪种情况,套接字都可能在未知的时间内保持打开状态。 下次我运行程序时,出现此错误: 现在,程序始终尝试使用相同的端口,因此看起来好像它仍处于打开状态。我检查了一下,很确定程序没有在后台运行,但是我的地址仍在使用中。 因此,如何

  • 问题内容: 我从python脚本生成了5个不同的进程,如下所示: 我的问题是,当父进程(主脚本)以某种方式被杀死时,子进程继续运行。 当父进程被杀死时,有没有办法杀死这样生成的子进程? 编辑:我正在尝试: 但这似乎不起作用 问题答案: 我自己也遇到了同样的问题,我有以下解决方案: 打电话之前,您可以设置。然后如此处所述python.org multiprocessing 进程退出时,它将尝试终止其

  • 问题内容: 我在前台启动了我的程序(守护程序),然后用杀死了它,但剩下一个僵尸,无法用杀死它。如何杀死僵尸进程? 如果僵尸是一个死进程(已被杀死),我如何将其从输出中删除? 问题答案: 僵尸已经死了,所以您无法杀死它。要清理僵尸,必须等待其父级等待,因此杀死父级应该可以消除僵尸。(父对象死后,僵尸将被pid 1继承,而pid 1将等待该僵尸并清除其在进程表中的条目。)如果守护程序正在生成成为僵尸的

  • 我基本上是想让bash脚本永远运行节点脚本。我制作了以下bash脚本: 我希望当它运行时,它用给定的脚本启动节点,检查节点是否退出,如果退出,Hibernate6秒,然后重新打开节点。另外,我希望它在后台运行,并将其pid(bash pid)写入一个名为“pid”的文件中。 显然,上面解释的一切都如预期的那样工作,但我也期望当bash脚本的pid被杀死时,节点脚本将停止运行,我不知道为什么在我看来

  • 问题内容: 我正在使用child_process.spawn()从在Ubuntu上运行的Node.JS应用程序启动脚本。据我所知,标准的分叉或生成的* nix进程通常不会在父进程死后死亡,但是当从Node.JS生成进程时,它们似乎在我的应用程序崩溃或被ctrl-c等终止时被杀死。 。 为什么会这样,并且有解决办法?我似乎在child_process API中找不到任何明显的选项。 我的应用程序启动

  • 每次重新启动时,在ubuntu上运行时,都会看到进程的负载 我想干掉所有这些进程(我不知道为什么它们在重新启动时运行,但它们会极大地降低我的cpu性能。) 我尝试了这里的每一个建议,停止并移除所有docker容器,但没有任何效果:进程仍在运行。 我怎么解决这个?