Node.js服务器GET在使用几个小时后分离API失败

在我的节点站点中,我调用了使用标准http get构build的restful API服务。 经过几个小时的沟通成功的工作,我发现请求停止发送,它只是等待,最终超时。

被调用的API仍然能够很好地接收来自其他地方的请求,但是当从站点发送请求时,它不会到达API。

我已经尝试了stream.pipe,util.pump,只是将文件写入文件系统。

我正在使用节点0.6.15。 我的网站和被调用的服务在同一台服务器上,所以正在调用localhost。 内存占用率大约为25%,CPU平均使用率约为10%。

一段时间后,我开始使用请求模块,但我得到相同的行为。 在失败varrys之前,它调用的数量似乎在5到100之间。最后,我必须重新启动站点,但不是API再次使其工作。

这里大概是什么在网站的代码看起来像:

var Request = require('request'); downloadPDF: function(req, res) { Project.findById(req.params.Project_id, function(err, project) { project.findDoc(req.params.doc_id ,function(err, doc) { var pdfileName; pdfileName = doc.name + ".pdf"; res.contentType(pdfileName); res.header('Content-Disposition', "filename=" + pdfileName); Request("http://localhost:3001/" + project._id).pipe(res); }); }); } 

我有很多可能发生的事情。

你是否尝试增加agent.maxSockets,或者禁用http.Agentfunction? 默认情况下,最近的节点版本使用套接字池为HTTP客户端连接,这可能是问题的根源http://nodejs.org/api/http.html#http_class_http_agent

我不确定你的Node服务器有多忙,但可能是你的所有套接字都处于TIME_WAIT状态。

如果你运行这个命令,你应该看到这个状态下有多less个套接字:

 netstat -an | awk '/tcp/ {print $6}' | sort | uniq -c 

有一些当然是正常的。 你只是不想最大化你的系统的可用套接字,并让他们都在TIME_WAIT。

如果是这样的话,你实际上想要减less agent.maxSockets设置(与@ user1372624的build议相反),否则每个请求只会接收一个新的套接字,即使它可以简单地重用一个新的套接字。 达到无响应状态只需花费更长的时间。

我发现这个Gist (http.Agent的补丁)可能会帮助你。

这个服务器错误的答案可能也有帮助: https : //serverfault.com/a/212127

最后,更新节点也可能会有所帮助,因为它们可能已经解决了自版本以来的保持活动行为(您可能会检查更改日志)。

您正在使用callback来返回一个没有多大意义的值,因为您的Project.findById()立即返回,而不等待提供的callback完成。

不过不过,nodejs使用的编程模型起初有些困难。

在事件驱动的编程(EDP)中,我们提供callback来完成结果,忽略它们的返回值,因为我们不知道callback实际上何时会被调用。

这是一个简单的例子。

假设我们想把一个HTTP请求的结果写入一个文件中。

在程序性(非EDP)编程环境中,我们依赖于只有在返回值时才返回值的函数。

所以我们可能会写(伪代码):

  url = 'http://www.example.com' filepath = './example.txt' content = getContentFromURL(url) writeToFile(filepath,content) print "Done!" 

它假设我们的程序将等到 getContentFromURL()已经联系远程服务器,发出请求, 等待结果并将结果返回给程序。

writeToFile()函数然后要求操作系统在某个文件path上打开一个本地文件进行写操作, 等待告知打开的文件操作已经完成(通常等待磁盘驱动程序报告它可以执行这样的操作。 )

writeToFile()然后请求操作系统将内容写入新打开的文件,等到被告知操作系统用来写文件的驱动程序告诉它已经完成了这个目标,然后把结果返回给程序,告诉我们该程序已经完成。

nodejs被创build来解决的问题是更好地利用上面发生的所有等待浪费的时间。

它通过使用函数(callback函数)来执行此操作,这些函数在从远程Web请求中检索结果或将文件写入文件系统的操作完成时调用。

要在事件驱动的编程环境中完成上述相同的任务,我们需要编写相同的程序:

  getContentFromURL(url,onGetContentFromURLComplete) function onGetContentFromURLComplete(content,err){ writeToFile(content,onWriteToFileComplete); } function onWriteToFileComplete(err){ print "Done!"; } 

哪里

  • 调用getContentFromURL()只会调用onGetContentFromURLCompletecallback,一旦它有Web请求的结果
  • 调用writeToFile()只调用其callback来显示成功消息,当它完成写入内容成功。

nodejs真正的魔力在于它可以在令人惊讶的大量时间内做各种其他的事情。程序function必须等待大部分时间密集型操作(比如与input和输出有关的操作)才能完成。

(上面的例子忽略了所有通常被认为是坏事的错误 。)

我也经历了使用内置函数的间歇性错误。 作为解决scheme,我使用本地wget。 我做了如下的事情

 var exec = require('child_process').exec; function fetchURL(url, callback) { var child; var command = 'wget -q -O - ' + url; child = exec(command, function (error, stdout, stderr) { callback(error, stdout, stderr); }); } 

经过一些小的改动,你可以使它适合你的需求。 到目前为止,这对我来说是坚实的。

你调用这个函数时是否尝试logging你的参数? 错误可能取决于req.params.Project_id。 你也应该在你的callback函数中提供error handling。

如果您可以确定某个参数集的失败请求(使其可重现),则可以使用节点检查器轻松地debugging应用程序。