How Do I Shut Down My Express Server Gracefully When Its Process Is Killed?

后端 未结 6 661
清酒与你
清酒与你 2020-12-08 00:50

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

6条回答
  •  失恋的感觉
    2020-12-08 00:58

    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.

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

提交回复
热议问题