2016-10-22 71 views
0

我希望基于Express.js的服务器能够在退出节点进程之前正确关闭所有连接当关闭信号(SIGTERM或SIGINT)被发送时。无法正常关闭节点+ Express应用程序(节点http服务器的关闭功能未完成)

我稍微修改了express-graceful-shutdown中间件(which is really simple),所以我的代码的相关部分看起来大致如下:

server.js

import gracefulShutdown from './tools/graceful-shutdown'; 

const server = app.listen(config.port,() => { 
    console.log(`Server is running`); 
}); 

app.use(gracefulShutdown(server)); 

优美,shutdown.js:

function gracefulShutdownMiddleware(server) { 

    let shuttingDown = false; 
    const forceTimeout = 10 * 1000; // giving the app 10 seconds to shutdown gracefully 


    process.on('SIGTERM', gracefulExit); // listen for TERM signal (e.g. kill) 
    process.on ('SIGINT', gracefulExit); // listen for INT signal (e.g. Ctrl-C) 

    function gracefulExit() { 

    if (shuttingDown) return; 
    shuttingDown = true; 
    console.log('Received kill signal (SIGTERM), shutting down'); 

    setTimeout(function() { 
     console.log('Could not close connections in time, forcefully shutting down'); 
     process.exit(1); 
    }, forceTimeout); 

    server.close(function() { 
     console.log('Closed out remaining connections.'); 
     process.exit(); 
    }); 

    } 

    function middleware(req, res, next) { 
    if (!shuttingDown) return next() 
    res.set('Connection', 'close') 
    res.status(503).send('Server is in the process of restarting.') 
    } 

    return middleware 

} 

export default gracefulShutdownMiddleware; 

问题我是观察是这样的。如果我在启动后立即关闭节点服务器,它会按预期关闭(中间件中的功能gracefulExit正常工作,server.close执行正常,并且回拨到server.close将打印出控制台消息)。但是,如果我打开浏览器并实际访问本地主机上的应用程序,以便服务器有一些工作要做,然后尝试关闭服务器,server.close函数似乎并未完成(所以它从不调用带有process.exit回调终于等到了setTimeout的调用它自己的回调,并有力地关闭应用程序。

的server.close功能是从节点的lib this function

能不能帮我弄清楚为什么节点服务器的close功能可能无法完成?

+0

可能的重复[如何关闭我的易捷版服务器,当它的进程被终止?](https://stackoverflow.com/questions/43003870/how-do-i-shut-down-my-express-服务器 - 正当进程 - 被终止) –

+0

您遇到了与上述问题相同的问题。也请随时[也检查我的答案](https://stackoverflow.com/a/44291800/1056679)。 –

回答

1

.close()实际上并没有关闭任何活动连接,它会启动请停止新的连接,并等待活动连接关闭(由客户端)。

如果连接的客户端保持连接处于打开状态(例如使用保持连接),则回调可能永远不会被调用。

有一个名为http-shutdown的软件包,可以帮助正常关闭HTTP服务器。

+0

谢谢!我通读了'http-shutdown'的代码,其方法似乎工作正常。尽管如此,我仍然对[这段代码](https://github.com/thedillonb/http-shutdown/blob/master/index.js#L29)有些困惑。 – azangru

+0

@azangru从它的外观,模块跟踪所有传入的连接(使它关闭时调用关闭),并且你所指的代码基本上清理完成的连接(所以它不会再被关闭关机时,因为连接已经完成)。 – robertklep