- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
我有一个非常基本的 http 服务器:
require("http").createServer(function (req, res) {
res.end("Hello world!");
}).listen(8080);
如何监听服务器崩溃以便发送 500
状态代码作为响应?
监听 process.on("uncaughtException", handler)
在 process
级别工作,但我没有请求和响应对象。
我看到的一个可能的解决方案是在 createServer
回调中使用 try - catch
语句,但我正在寻找是否有更好的解决方案。
我尝试在 server
对象上监听 error
事件,但没有任何反应:
var s = require("http").createServer(function (req, res) {
undefined.foo; // test crash
res.end("Hello world!");
});
s.on("error", function () { console.log(arguments); });
s.listen(8080);
最佳答案
您可以使用 Node 的内置 domain module为了这。
Domains provide a way to handle multiple different IO operations as a single group. If any of the event emitters or callbacks registered to a domain emit an error event, or throw an error, then the domain object will be notified, rather than losing the context of the error in the process.on('uncaughtException') handler, or causing the program to exit immediately with an error code.
需要注意的一件非常重要的事情是:
Domain error handlers are not a substitute for closing down your process when an error occurs.
By the very nature of how throw works in JavaScript, there is almost never any way to safely "pick up where you left off", without leaking references, or creating some other sort of undefined brittle state.
由于您只是询问如何响应 (请参阅下一节关于重新启动该过程)500
错误,因此我不会深入探讨如何处理重启服务器等,例如 Node 文档确实如此; 我强烈推荐 taking a look at the example in the node docs 。他们的示例展示了如何捕获错误,将错误响应发送回客户端(如果可能),然后重新启动服务器。我将只展示域创建和发回 500
错误响应。
域的工作方式类似于将 try
/catch
放入您的 createServer
回调中。在你的回调中:
错误
事件req
和 res
添加到域中(因为它们是在域存在之前创建的)run
域并调用您的请求处理程序(这就像 try
/catch
的 try
部分>)像这样:
var domain = require('domain');
function handleRequest(req, res) {
// Just something to trigger an async error
setTimeout(function() {
throw Error("Some random async error");
res.end("Hello world!");
}, 100);
}
var server = require("http").createServer(function (req, res) {
var d = domain.create();
d.on('error', function(err) {
// We're in an unstable state, so shutdown the server.
// This will only stop new connections, not close existing ones.
server.close();
// Send our 500 error
res.statusCode = 500;
res.setHeader("content-type", "text/plain");
res.end("Server error: " + err.message);
});
// Since the domain was created after req and res, they
// need to be explictly added.
d.add(req);
d.add(res);
// This is similar to a typical try/catch, but the "catch"
// is now d's error event.
d.run(function() {
handleRequest(req, res);
});
}).listen(8080);
通过使用 cluster
模块,您可以在出错后很好地重新启动进程。我基本上是从此处的 Node 文档中复制示例,但总体思路是从主进程启动多个工作进程。工作人员是处理传入连接的进程。如果其中一个有不可恢复的错误(即我们在上一节中捕获的错误),那么它将与主进程断开连接,发送 500 响应,然后退出。当主进程看到工作进程断开连接时,它会知道发生了错误并启动了一个新的工作进程。由于有多个工作进程同时运行,因此如果其中一个出现故障,应该不会出现丢失传入连接的问题。
示例代码,复制自 here :
var cluster = require('cluster');
var PORT = +process.env.PORT || 1337;
if (cluster.isMaster) {
// In real life, you'd probably use more than just 2 workers,
// and perhaps not put the master and worker in the same file.
//
// You can also of course get a bit fancier about logging, and
// implement whatever custom logic you need to prevent DoS
// attacks and other bad behavior.
//
// See the options in the cluster documentation.
//
// The important thing is that the master does very little,
// increasing our resilience to unexpected errors.
cluster.fork();
cluster.fork();
cluster.on('disconnect', function(worker) {
console.error('disconnect!');
cluster.fork();
});
} else {
// the worker
//
// This is where we put our bugs!
var domain = require('domain');
// See the cluster documentation for more details about using
// worker processes to serve requests. How it works, caveats, etc.
var server = require('http').createServer(function(req, res) {
var d = domain.create();
d.on('error', function(er) {
console.error('error', er.stack);
// Note: we're in dangerous territory!
// By definition, something unexpected occurred,
// which we probably didn't want.
// Anything can happen now! Be very careful!
try {
// make sure we close down within 30 seconds
var killtimer = setTimeout(function() {
process.exit(1);
}, 30000);
// But don't keep the process open just for that!
killtimer.unref();
// stop taking new requests.
server.close();
// Let the master know we're dead. This will trigger a
// 'disconnect' in the cluster master, and then it will fork
// a new worker.
cluster.worker.disconnect();
// try to send an error to the request that triggered the problem
res.statusCode = 500;
res.setHeader('content-type', 'text/plain');
res.end('Oops, there was a problem!\n');
} catch (er2) {
// oh well, not much we can do at this point.
console.error('Error sending 500!', er2.stack);
}
});
// Because req and res were created before this domain existed,
// we need to explicitly add them.
// See the explanation of implicit vs explicit binding below.
d.add(req);
d.add(res);
// Now run the handler function in the domain.
d.run(function() {
handleRequest(req, res);
});
});
server.listen(PORT);
}
// This part isn't important. Just an example routing thing.
// You'd put your fancy application logic here.
function handleRequest(req, res) {
switch(req.url) {
case '/error':
// We do some async stuff, and then...
setTimeout(function() {
// Whoops!
flerb.bark();
});
break;
default:
res.end('ok');
}
}
注意:我还是要强调,你应该看看domain
module documentation并查看那里的示例和解释。它解释了大部分(如果不是全部)、其背后的原因以及您可能会遇到的其他一些情况。
关于javascript - 处理 http 服务器崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25957449/
据我了解,HTTP POST 请求的正文大小没有限制。因此,客户端可能会在一个 HTTP 请求中发送 千兆字节 的数据。现在我想知道 HTTP 服务器应该如何处理此类请求。 Tomcat 和 Jett
在了解Web Deploy我遇到了一些讨论 http://+:80 和 http://*:80 的 netsh.exe 命令。这些是什么意思? 最佳答案 引自URLPrefix Strings (Wi
假设我有一个负载均衡器,然后是 2 个 Web 服务器,然后是一个负载均衡器,然后是 4 个应用程序服务器。 HTTP 响应是否遵循与 HTTP 请求服务相同的路径? 最佳答案 按路径,我假设您是网络
我有一个带有 uri /api/books/122 的资源,如果在客户端为此资源发送 HTTP Delete 时该资源不存在,那么相应的响应代码是什么这个 Action ?是不是404 Not Fou
是否有特定的(或约定的)HTTP 响应消息(或除断开连接之外的其他操作)来阐明服务器不接受 pipelined HTTP requests ? 我正在寻找能让客户端停止流水线化它的请求并分别发送每个请
在了解Web Deploy我遇到了一些讨论 http://+:80 和 http://*:80 的 netsh.exe 命令。这些是什么意思? 最佳答案 引自URLPrefix Strings (Wi
我有一个带有 uri /api/books/122 的资源,如果在客户端为此资源发送 HTTP Delete 时该资源不存在,那么相应的响应代码是什么这个 Action ?是不是404 Not Fou
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 8 年前。 Improve this qu
我使用 Mule 作为 REST API AMQP。我必须发送自定义请求方法:“PRINT”,但我收到: Status Code: 400 Bad Request The request could
我需要针对具有不同 HTTP 响应代码的 URL 测试我的脚本。我如何获取响应代码 300、303 或 307 等的示例/示例现有 URL? 谢谢! 最佳答案 您可以使用 httpbin为此目的。 例
我正在尝试编写一个程序来匹配 HTTP 请求及其相应的响应。似乎在大多数情况下一切都运行良好(当传输完全有序时,即使不是,通过使用 TCP 序列号)。 我发现的唯一问题是当我有流水线请求时。在那之后,
RESTful Web Services鼓励使用 HTTP 303将客户端重定向到资源的规范表示。它仅在 HTTP GET 的上下文中讨论主题。 这是否也适用于其他 HTTP 方法?如果客户端尝试对非
当使用chunked HTTP传输编码时,为什么服务器需要同时写出chunk的字节大小并且后续的chunk数据以CRLF结尾? 这不会使发送二进制数据“CRLF-unclean”和方法有点多余吗? 如
这个问题在这里已经有了答案: Is it acceptable for a server to send a HTTP response before the entire request has
如果我向同一台服务器发出多个 HTTP Get 请求并收到每个请求的 HTTP 200 OK 响应,我如何使用 Wireshark 判断哪个请求映射到哪个响应? 目前看起来像是发出了一个 http 请
func main() { http.HandleFunc("/", handler) } func handler(w http.ResponseWriter, r http.Request
我找不到有值(value)的 NodeJS with Typescript 教程,所以我在无指导下潜入水中,果然我有一个问题。 我不明白这两行之间的区别: import * as http from
问一个关于Are HTTP headers case-sensitive?的问题,如果 HTTP 方法区分大小写,大多数服务器如何处理“get”或“post”与“GET”或“POST”? 例如,看起来
我正在使用ASP.NET,在其中我通过动词GET接收查询,该应用程序专用于该URL。 该代码有效,但是如果用户发送的密码使http 200无效,请回答我,并在消息的正文中显示“Fail user or
Closed. This question needs details or clarity。它当前不接受答案。 想改善这个问题吗?添加详细信息,并通过editing this post阐明问题。 9
我是一名优秀的程序员,十分优秀!