Node.js + Express随机丢弃请求,导致网关超时

编辑

经过多次的酝酿,我终于find了一个看起来可能是稳固的领导者:

快速库在当前正在使用Node + OAuth模块执行多个出站请求(例如Facebook,Twitter等)时无法接受传入的请求。 我可以通过在我的代码中放置大量日志来确定这一点,我发现在出站请求的中间没有触发“开始 – 请求”日志(如下所述)。

我已经能够certificate,当Node + OAuth模块发出几个出站请求时,对我的API(通过浏览器窗口)的入站请求将挂起,直到其中一个出站OAuth请求完成,才会被接收。

当然,我已经做了:

require('http').globalAgent.maxSockets = 999; 

根据IRC的build议,我补充说

 console.log(require('http').globalAgent.requests); 

但是这似乎总是=== {},意味着没有待处理的入站请求AFAIK。

因此,我只能得出结论,无论是node.js还是express,出于某种原因都select阻止由于出站请求而引起的传入请求,即使应该有足够的套接字可用。

任何人有任何提示如何解决这个问题?


我有一个使用Express,Mongoose等在Amazon云上部署的node.js中创build的API,这个API在99%的时间里工作起来非常快。

除此之外,一段时间以来,一个请求似乎有所下降或被忽略。 我正在谈论通常以毫秒为单位完成的请求,随机地没有反应,没有清晰的图像为什么

当连接到API端点时,症状是一个简单的“网关超时”。 一个相同的请求,从相同的客户端使用相同的参数,只是在瞬间之前或之后,将工作得很好。

当然,我的第一个想法是“服务器超负荷!” 所以我花了很多时间优化我的请求,monogoDB等等。最后,我发现整个电路板(在Node.js服务器和Mongo服务器中)的CPU /磁盘/ RAM使用率都非常低。 我使用Scout和RightScale实时跟踪我的服务器,并且logging超过100ms的任何请求或查询。 我的节点服务器目前有5GB的可用内存,70%的空闲CPU(第一核心)等,所以我99.99%肯定这不是一个性能问题。

最后,我铤而走险尝试了一下:我随机附上了一个随机数,以表示我的客户提出的所有请求。 然后,在node.js应用程序中,当请求第一次被接收并且完成时,我做了一个console.log()。 例如,这里是我使用的中间件:

 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的Web应用程序,我打印与请求发送到控制台的“鲁伊”。 每当请求成功时,node.js控制台中都会显示相应的“ruid”。 每当它超时,就没有了。


编辑:更多的debugging和信息。

我的应用程序服务器实际上开始(并继续)也为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,然后在本地主机上创build了一个简单的PHP + CURL脚本,用随机的URL打开我的api.streamified.me(这应该会导致node.js触发一个简单的“未find”响应),直到导致网关超时。 在这里,你可以看到它已经发生了 – 重写日志显示请求被应用服务器肯定接收并转发到端口8888 …但是它从来没有被node.js收到(或者至less第一行中间件的第一行代码从来没有得到它)

在这里输入图像描述


我一直在我的node.js代码,我很确定,我没有阻止代码,即使我做了,我无法想象它阻止线程足够长的时间错过一个请求,而不会引起红旗在某处。

我错过了什么? 传入的套接字是否会被阻塞? 我通过我的node.js应用程序向外部API做了相当多的HTTP请求,但是AFAIK不应阻塞传入的套接字。


当然,我有错误日志logging。 我已经在stream程级别上启用了它…

 process.addListener("uncaughtException", function (err) { // some logging code } 

和Express级别(上面的onError处理程序)。 我知道我的错误loggingfunction工作,因为我看到他们都在之前火。 但是他们两个都没有报告任何请求,也没有在控制台中看到任何东西。


  • Express版本:3.0.0rc5
  • Node.js版本:0.8.12
  • 在标准Amazon Cloud安装(m1.large实例)上运行的2个node.js应用实例,位于2个负载均衡器之后,连接到一个3x副本的MongoDB集(也是m1.large)

这听起来像你是locking你的节点线程太长,导致传入连接超时处理它们。 节点是单线程的,所以它一次只能做一件事,它不能select阻止一个传入的请求。 它只能接受一个传入的请求,因为它忙于做别的事情。 你需要弄清楚忙什么。

如果你不做出站请求,一切工作正常? 如果是这样,你需要看看这些请求的代码,以确保你没有等待回应。