gpt4 book ai didi

node.js - http.createServer 中的 'uncaughtException'

转载 作者:搜寻专家 更新时间:2023-11-01 00:46:42 24 4
gpt4 key购买 nike

如果错误,我想在请求中 res.end('server error') 。我的代码:

http.createServer(function(req,res){
process.on('uncaughtException', function() {
res.end('server error')
})
handlers(req,res)
}).listen(1337)

我的决定有什么问题?

最佳答案

你会收到这样的错误/警告:

(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.
Trace:
at EventEmitter.<anonymous> (events.js:139:15)
at EventEmitter.<anonymous> (node.js:389:29)
at Server.<anonymous> (/Users/taf2/work/phonetrac/services/ctm-pool/foo.js:2:11)
at Server.emit (events.js:70:17)
at HTTPParser.onIncoming (http.js:1572:12)
at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:91:29)
at Socket.ondata (http.js:1468:22)
at TCP.onread (net.js:374:27)

我假设您正在执行上述操作,因为您注意到当您开始捕获 uncaughtException 时,客户端连接不再关闭,因此,如果发生错误,客户端连接将永远不会被释放。例如,如果您将 node.js 端点作为客户端请求嵌入到脚本标记中,例如

<script src="http://127.0.0.1:1337/yourendpoint.js"></script>

这将挂起您服务的使用者...希望您使用异步技术嵌入您的脚本...

无论如何,如果您处理释放事件监听器,使用您的技术处理错误是可行的。

function handleError(err) {
console.error("Caught exception:", err, err.stack);
this.end();
this.emit("cleanup");
}

require('http').createServer(function(req, res) {
var errorHandler = handleError.bind(res)
process.on("uncaughtException", errorHandler);
res.on("cleanup", function() { process.removeListener("uncaughtException", errorHandler); });

this.is.an.error;

res.end();
res.emit("cleanup");
}).listen(1337);

尝试一下,我们没有泄漏,我们的错误得到处理,连接关闭,让我们的客户可以自由地继续处理下一个错误:

ab -n 100 -c 10 http://127.0.0.1:1337/

但是,如果您的服务器执行以下任何复杂操作,此解决方案将在并发情况下崩溃:

function handleError(err) {
console.error("Caught exception:", err, err.stack);
this.end();
this.emit("error:cleanup");
}

require('http').createServer(function(req, res) {
var errorHandler = handleError.bind(res)
process.on("uncaughtException", errorHandler);
res.on("error:cleanup", function() { process.removeListener("uncaughtException", errorHandler); });

setTimeout(function() {
this.is.an.error;
res.end();
res.emit("cleanup");
},1000);

}).listen(1337);

这里的问题是所有错误都会触发 uncaughtException 并且它们会重叠。这意味着要捕获这样的全局错误,最好只有一个 process.on("uncaughtException"处理程序。

在上述情况下,您需要:

  • 有一个独立的 try { } catch {} block - 这可能很难做到正确。
  • 允许异常未被捕获并使进程崩溃,使用 monit 或类似的东西重新启动进程。
  • 您可以尝试使用具有 setInternval 清除功能的数组来过滤掉已关闭的连接。

下面是使用setInterval。

var connectionIndex = 0;
var connections = [];

function handleError(err) {
console.error("Caught exception:", err, err.stack);
connections.forEach(function(conn) {
conn.end();
});
}

var server = require('http').createServer(function(req, res) {
connections.push(res.connection);

setTimeout(function() {
this.is.an.error;
res.end();
},100);

});

setInterval(function() {
console.log("conn check: %d", connections.length);
connections = connections.filter(function(conn) {
return !conn.destroyed;
});
},1000);

process.on("uncaughtException", handleError);

server.listen(1337);

我有点喜欢最后一个解决方案,但我确信它可能有一些优势,所以使用第二个解决方案有一个监控服务来重启你的服务器可能是最好的。

关于node.js - http.createServer 中的 'uncaughtException',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10018402/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com