我有一个nodejs服务器运行express来服务器输出http调用。如果出现问题,是否有建议的方法来优雅地关闭服务器?我应该以某种方式让服务器运行吗?
即。在一个未被捕获的异常上,服务器就停止了,我认为这会杀死连接的客户端,而不是将它们交给响应者。
我应该:
这是正确的吗?
process.on('exit', function () {
console.log('About to exit, waiting for remaining connections to complete');
app.close();
});
在这种情况下,可能会抛出错误,使服务器处于未定义状态,服务器将继续完成剩余连接。
有没有什么好方法可以处理错误继续运行,还是我应该让服务器死掉并重启?
答案 0 :(得分: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(); });
当节点存在时,该函数应该运行,而不是实际告诉节点退出。这是您可以结束流程的一种方式,但它不会优雅地结束:
<强>
process.exit([code])
强>使用指定的代码结束进程。如果省略,则退出使用 '成功'代码
0
。以“失败”代码退出:
process.exit(1);
执行节点的shell应该看到退出代码 为1
。
请参阅http://nodejs.org/api/process.html
我希望这有帮助!
答案 1 :(得分: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);
}
});
});
Express'next
函数将错误作为其第一个参数。如果您使用错误参数调用next
,它将停止处理路由并查找error handler,或者只返回500。
当然,在try
/ catch
中包装所有内容可能有点过分;大多数事情实际上并没有抛出异常。只有在知道可能会抛出的东西时才应该这样做。否则,您可能会因吞咽异常而陷入一种非常难以调试的不一致状态。
重要的是要记住,一旦抛出意外异常,您的应用程序就处于未定义状态。问题请求可能永远不会完成,您的应用程序永远不会重新启动。或者可能发生任何其他奇怪的事情。 (这是数据库问题吗?文件系统?内存损坏?)
这些情况难以诊断,更不用说调试了。快速失败,崩溃并快速重启服务器会更安全,也可以说更好。是的,任何碰巧连接的客户都会被切断,但只需重试即可轻松完成。
如果您担心可用性,请使用cluster module以便运行多个(通常是CPU核心数)服务器进程,并且一次崩溃不会导致整个站点崩溃。
答案 2 :(得分:0)
如果您使用快递,那么您可以使用此npm模块优雅地处理关闭。