Nodejs/express,优雅地关闭

los*_*ion 11 node.js express

我有一个nodejs服务器运行express来服务器输出http调用.如果出现问题,是否有建议的方法来优雅地关闭服务器?我应该以某种方式让服务器运行吗?

IE在一个未被捕获的异常上服务器刚停止,我认为这会杀死已连接的客户端而不是将它们交回响应.

我是不是该:

  1. 在我允许服务器死亡(然后重新启动)之前,等待所有http连接完成.
  2. 或者我应该尝试阻止服务器永远死亡?

这是对的吗?

process.on('exit', function () {
  console.log('About to exit, waiting for remaining connections to complete');
  app.close();
});
Run Code Online (Sandbox Code Playgroud)

在这种情况下,可能会抛出错误,使服务器处于未定义状态,服务器将继续完成剩余连接.

是否有任何好方法来处理错误继续运行或我应该让服务器死并重新启动?

小智 8

当NodeJS不期待任何事情发生时,它将关闭; 当http服务器正在等待连接节点保持运行时.

server.close([callback])

阻止服务器接受新连接并保留现有连接.此函数是异步的,当所有连接都结束并且服务器发出close 事件时,服务器最终会关闭.(可选)您可以传递回调以侦听close 事件.

执行此操作后,服务器将继续运行,直到最后一次连接完成,然后正常关闭.

如果您不想等待连接终止,则可以使用socket.end()socket.destroy()继续使用其他连接.

http://nodejs.org/api/net.html


process.on('exit', function () {
    console.log('About to exit, waiting for remaining connections to complete');
    app.close();
});
Run Code Online (Sandbox Code Playgroud)

此节点应该在节点存在时运行,而不是实际告诉节点退出.这是您可以结束流程的一种方式,但它不会优雅地结束:

process.exit([code])

使用指定的代码结束进程.如果省略,则退出使用"成功"代码0.

要使用"失败"代码退出:

process.exit(1);执行节点的shell应该看到退出代码为1.

http://nodejs.org/api/process.html


我希望这有帮助!


jos*_*736 8

不要试图用未处理的例外做任何事情.让服务器死掉.

通常,如果路由处理程序抛出异常,Express将只捕获它并将HTTP 500返回给客户端.由于Express捕获了异常,因此您的服务器不会崩溃.

关闭服务器通常会发生的事情是在回调中抛出异常的时候; 例如:

app.get('/foo', function(req, res) {
    db.query(..., function(err, r) {
        throw new Error(); // oops, we'll crash
    });
});
Run Code Online (Sandbox Code Playgroud)

因为回调自然地在Express路由器调用堆栈之外执行,所以无法将其与特定请求相关联.但是,你可以防范这种情况:

app.get('/foo', function(req, res, next) {
    db.query(..., function(err, r) {
        try {
            throw new Error();
        } catch(ex) {
            next(ex);
        }
    });
});
Run Code Online (Sandbox Code Playgroud)

Express' next函数将错误作为其第一个参数.如果next使用error参数调用,它将停止处理路由并查找错误处理程序,或者只返回500.

当然,包装try/ catch可能是矫枉过正; 大多数事情实际上并没有抛出异常.如果你知道可能会抛出一些东西,你应该这样做.否则,通过吞咽异常可能最终导致难以调试的不一致状态.

重要的是要记住,一旦抛出意外异常,您的应用程序就处于未定义状态.问题请求可能永远不会完成,您的应用程序永远不会重新启动.或者可能发生任何其他奇怪的事情.(它是数据库问题吗?文件系统?内存损坏?)

这些情况难以诊断,更不用说调试了.快速失败,崩溃并快速重启服务器会更安全,也可以说更好.是的,任何碰巧连接的客户都会被切断,但是他们只需重试即可.

如果您担心可用性,请使用群集模块,以便运行多个(通常是CPU核心数)服务器进程,并且一个崩溃不会导致整个站点崩溃.