进程被杀死后,如何正常关闭Express Server? [英] How Do I Shut Down My Express Server Gracefully When Its Process Is Killed?

查看:504
本文介绍了进程被杀死后,如何正常关闭Express Server?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

When running my Express application in production, I want to shut down the server gracefully when its process is killed (i.e. a SIGTERM or SIGINT is sent).

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

Here is a simplified version of my code:

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函数中,将一直打印当前打开1个连接",直到我真正关闭浏览器窗口为止.显然,即使关闭选项卡也会使连接保持打开状态.

When I run it and call the URL http://localhost:3000/ in a browser, the log statement in the setInterval function will keep printing "1 connection currently open" until I actually close the browser window. Even closing the tab will keep the connection open, apparently.

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

So wenn I kill my server by hitting Ctrl+C, it will run into the timeout and print "Could not close connections" after 10 seconds, all the while continuing to print "1 connection open".

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

Only if I close the browser window before killing the process I get the "closed out remaining connections" message.

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

推荐答案

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

In case anyone is interested, I found a solution myself (would love to hear feedback in comments).

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

I added a listener for connections opening on the server, storing references to those connections in an array. When the connections are closed, they are removed from the array.

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

When the server is killed, each of the connection is closed by calling its end methods. For some browsers (e.g. Chrome), this is not enough, so after a timeout, I call destroy on each connection.

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);
}

这篇关于进程被杀死后,如何正常关闭Express Server?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆