最初我想问一个关于如何基于Node.js创建robuts web服务器的问题。但是,这可能是一个非常大且含糊不清的问题。因此,我将其分解为创建robuts Web服务器时遇到的小问题和具体问题。
因此,我面临的一个挑战是如何捕获Node.js中所有未处理的错误?我想这样做,因为我不希望任何未处理的错误阻止Node.js运行,导致Web服务器关闭。
我想到的解决方案是将服务器运行代码块放在try-catch块中以捕获所有未处理的错误。但是,如果异步方法发生任何错误,则无效。例如,我的Web服务器可能看起来像下面的代码:
var fs = require('fs');
var http = require('http');
try {
// Here is my main web server, it could happen errors by adding
// more and more modules and functionalities to my server.
// I need to catch all unhandled errors to prevent server from crashing
// So, I put my whole server running in a try-catch block, but any error from
// an async method could not be caught!
http.createServer(function(req, res) {
throw Error("An unhandled error happens!");
}).listen(1234);
}catch (e){
console.log("An unhandled error caught!")
}
console.log('Server is listening to port 1234');
那么,我是否在正确的错误处理方向上确保服务器没有停止?还是有其他机制让服务器从错误中恢复?
答案 0 :(得分:4)
您需要使用domains。
一个全局域,每个请求包装所有服务器和一个域。如果在初始化期间出现错误,全局域将捕获错误,然后您可以记录它,执行一些清理任务并终止服务器。如果您从请求中收到错误,请将其记录为具有最高优先级并继续提供其他请求。这就是node.js希望我们编写健壮的Web服务器的方式。
主要问题是尝试尽可能优雅地关闭。优雅的退出意味着当你需要杀死服务器时(从ctrl-c或sigint或错误或其他),而不是做一个简单的process.exit(1)
,你必须清理资源,如关闭数据库连接,关闭文件,通知某人您不能使用process.on("exit", ...)
,因为当调用处理程序时,事件循环不起作用,您无法执行异步任务。
另外,如果您使用worker,当服务器需要关闭时,如何正常关闭它们?
你如何处理快递错误?
所有这些东西看起来都很复杂,总能保证正常关机。这就是我做node-grace的原因。
答案 1 :(得分:1)
如果使用Express是一个选项,我建议使用它而不是相当低级别的http
模块。使用Express,您可以很好地处理错误:
var express = require('express');
var app = express();
app.get('/', function(req, res) {
throw Error("An unhandled error happens!");
});
app.use(function(err, req, res, next) {
console.log('error', err);
res.send(500); // send a proper HTTP 500 message back to the client
});
app.listen(1234);
console.log('Server is listening to port 1234');
否则,请查看Node
的domain模块答案 2 :(得分:1)
在回调函数中使用try / catch:
var fs = require('fs');
var http = require('http');
try {
http.createServer(function(req, res) {
try{
// some code trowing erors
}catch(e){
console.log("error: " + e);
}
}).listen(1234);
}catch (e){
console.log("An unhandled error caught!")
}
console.log('Server is listening to port 1234');
为什么会这样?异步http回调不会像设置http服务器回调函数的代码一样运行(此外,每次服务器获取请求时都会调用该函数)。试试你自己:
try{
throw Error("An unhandled error happens!");
}catch(e){
console.log(e)
}
和
try{
process.nextTick(function(){
throw Error("An unhandled error happens!")
});
}
catch(e){
console.log(e)
}