13

我有一个运行 express 的 nodejs 服务器来处理 http 调用。如果发生不好的事情,是否有推荐的方法来优雅地关闭服务器?我应该让服务器以某种方式运行吗?

IE 在服务器刚刚停止的未捕获异常上,我认为这会杀死连接的客户端,而不是把它们交还给响应。

我是不是该:

  1. 在我允许服务器死机(然后重新启动它)之前等待所有 http 连接完成。
  2. 还是我应该尝试阻止服务器死机?

这合适吗?

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

在这种情况下,可能会引发错误,使服务器处于未定义状态,并且服务器将继续完成剩余的连接。

有什么好的方法来处理错误继续运行还是我应该让服务器死掉并重新启动?

4

3 回答 3

15

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

此函数应在节点存在时运行,而不是实际告诉节点退出。这是结束进程的一种方法,但它不会优雅地结束:

process.exit([code])

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

使用“失败”代码退出:

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

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


我希望这有帮助!

于 2013-06-30T19:45:27.580 回答
8

不要试图对未处理的异常做任何花哨的事情。让服务器死掉。

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

导致服务器宕机的通常情况是在回调中抛出异常;例如:

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

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

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

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

当然,将所有内容都包含在try/catch中可能有点过头了。大多数事情实际上并没有引发异常。仅当您知道某些东西可能会抛出时,您才应该这样做。否则,您可能会通过吞咽异常而最终陷入非常难以调试不一致状态的状态。

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

这些情况很难诊断,更不用说调试了。快速失败、崩溃和快速重启服务器更安全,可以说更好。是的,任何碰巧连接的客户端都会被切断,但它们很容易重试。

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

于 2013-07-01T03:33:17.417 回答
0

如果您使用的是 express,那么您可以使用这个 npm 模块来优雅地处理关闭。

https://www.npmjs.com/package/express-graceful-shutdown

于 2016-05-19T10:41:12.610 回答