修改
经过大量的讨论后,我终于发现了一些似乎可能是一个坚实领导的东西:
当快递库当前正在使用Node + OAuth模块执行多个出站请求(例如,Facebook,Twitter等)时,它无法接受传入请求。我能够通过在我的代码中放入大量日志来确定这一点,在那里我发现了" begin-request"在出站请求中间未触发日志(如下所述)。
我已经能够证明,当Node + OAuth模块发出一些出站请求时,对我的API的入站请求(通过浏览器窗口)将挂起,直到其中一个出站OAuth请求有结束。
当然,我已经完成了:
require('http').globalAgent.maxSockets = 999;
根据IRC的建议,我已添加
console.log(require('http').globalAgent.requests);
但这似乎总是=== {},暗示没有待处理的入境请求AFAIK。
因此,我得出结论,由于某些原因,node.js或express选择阻止由于出站请求而传入的请求,即使应该有足够的套接字可用...
有人对如何解决这个问题有任何暗示吗?
我在node.js中使用部署在Amazon Cloud上的Express,Mongoose等创建了一个API,99%的时间都可以非常快速地运行。
除了偶尔,一个请求似乎以某种方式被删除或被忽略。我正在谈论通常在几毫秒内完成的请求,这些请求随机无响应,没有清晰的图片为什么。
症状是一个简单的网关超时"连接到API端点时。一个相同的请求,在同一个客户端使用相同的参数,只是在之前或之后不久,将会正常工作。
当然,我的第一个想法是&#34; duh,服务器超载!&#34;所以我花了很多时间来优化我的请求,monogoDB等。最后我得到了全面的CPU /磁盘/ RAM使用(在Node.js服务器和Mongo服务器中)非常< / strong>低。我使用Scout和RightScale实时跟踪我的服务器,并记录任何超过100毫秒的请求或查询。我的节点服务器目前有5GB的免费RAM,70%的免费CPU(在第一核心上)等等。所以我99.99%肯定这不是性能问题。
最后,我又绝望了:我在客户提出的所有请求中附加了一个随机数字。然后,在node.js应用程序中,我在第一次收到请求时以及完成请求时执行console.log()。例如,这里是我在express中使用的中间件:
var configureAPI = function() {
return function(req, res, next) {
if(req.body.ruid)
console.log(req.body.ruid);
// more middleware stuff...
};
}
server.configure(function(){
server.use(express.bodyParser());
server.use(configureAPI());
server.use(onError);
// ... more config stuff
}
我发现震惊了我:显然, node.js应用甚至没有收到有问题的请求。我有一个Javascript webapp,我打印了#34; ruid&#34;随请求一起发送到控制台。只要请求成功,就会有相应的&#34; ruid&#34;打印在node.js控制台中。每当它超时,就没有。
编辑:更多调试&amp;资讯
我的应用服务器实际上已启动(并继续)也为PHP提供服务(因此,他们安装了Apache等)。我需要http://streamified.me来提供我的网站(PHP)和http://api.streamified.me来提供我的API(node.js)...所以我在httpd.conf文件中有一行来导致api.streamified请求.me(而不是streamified.me)通过端口8888转到node.js:
RewriteCond %{HTTP_HOST} ^api.streamified.me
RewriteRule ^(.*) http://localhost:8888$1 [P]
因此,在同一个httpd.conf文件中,我打开了RewriteLogLevel 5,然后在我的localhost上创建了一个简单的PHP + CURL脚本,用随机URL命中我的api.streamified.me(这会导致node.js到触发一个简单的&#34;未找到&#34;响应),直到它导致网关超时。在这里,您可以看到它已经发生 - 并且重写日志显示该请求肯定是由应用服务器接收并转发到端口8888 ......但它从未被node.js收到(或者,至少,第一行中间件中的第一行代码永远不会得到它......)
我已经遍及我的node.js代码并且我非常确定我没有阻止代码,即使我这样做了,我无法想象它会阻塞该线程足够长的时间而不会错过请求某处有红旗。
我错过了什么?是否有某些原因阻止传入的套接字?我通过我的node.js应用程序向外部API发出了相当多的HTTP请求,但AFAIK不应该阻止传入的套接字。
当然,我有错误记录到位。我在流程级别启用了它...
process.addListener("uncaughtException", function (err) {
// some logging code
}
并在Express级别(上面的onError处理程序)。我知道我的错误记录功能可以正常工作,因为我之前已经看过它们。但他们都没有报告任何被删除请求的时间,也没有在控制台中看到任何内容......
答案 0 :(得分:1)
听起来你的Node线程锁定时间太长,导致传入的连接在处理它们之前超时。节点是单线程的,因此它一次只做一件事,它不能选择阻止传入请求导致的传入请求。它只能接受传入的请求,因为它正忙于做其他事情。你需要弄清楚它在做什么。
如果您没有提出出站请求,一切正常吗?如果是这样,您需要查看发出这些请求的代码,以确保您不会等待响应。