多putzing身边后,我终于找到的东西,好像它可能是一个固体铅:
快递库在当前使用Node + OAuth模块执行多个出站请求(例如,Facebook,Twitter等)时未能接受传入请求。我可以通过在我的代码中放置大量日志来确定这一点,我发现在出站请求中间没有触发“开始 - 请求”日志(如下所述)。
我已经能够证明,当Node + OAuth模块发出几个出站请求时,通过浏览器窗口对我的API的入站请求将挂起并且不会被接收,直到其中一个出站OAuth请求已完成。
当然,我已经做了:
require('http').globalAgent.maxSockets = 999;
每一个建议在IRC,我已经添加
console.log(require('http').globalAgent.requests);
但这似乎总是=== {},这意味着没有待处理的入站请求AFAIK。
因此我留下得出结论,无论是Node.js的或表达的是选择到,出于某种原因,由于出站请求块传入的请求,即使应该有大量可用的套接字...
任何人有任何提示如何解决这个问题?
我在使用快递,猫鼬等,部署在Amazon云这奇妙的作品和快速的99%的时间node.js中创建的API。
除了,过一段时间,请求似乎不知何故掉落或忽略。我正在讨论通常以毫秒为单位完成的请求,并且没有任何清晰的图像,因此随机无响应为什么。
症状是一个简单的“网关超时”连接到API端点时。在同一个客户端使用相同的参数创建一个相同的请求,就在之前或之后的某个时刻,可以很好地工作。
当然,我首先想到的是“咄,服务器超载!”所以我花了很多时间来优化我的请求,monogoDB等等。最后,我发现整个电路板(包括Node.js服务器和Mongo服务器)的CPU /磁盘/ RAM使用率为非常低。我使用Scout和RightScale实时跟踪我的服务器,并且记录超过100ms的任何请求或查询。我的节点服务器目前有5GB的可用内存,70%的可用CPU(第一核心)等等,所以我99.99%肯定这不是性能问题。
最后,我就拼命回落:我重视我的客户(S)由随机数所有请求。然后,在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
}
我找到了什么让我震惊:显然,节点。js应用程序甚至没有收到有问题的请求。我有一个JavaScript web应用程序,并打印与请求一起发送到控制台的“ruid”。只要请求成功,node.js控制台中就会显示相应的“ruid”。每当它超时,就没有。
编辑:更多调试&信息。
我的应用程序服务器实际上启动(并继续)也提供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,然后创建一个简单的PHP +卷曲脚本在我的本地打我的API。用随机的URL(这会导致node.js触发一个简单的“not found”响应)streamified.me,直到它导致网关超时。在这里,你可以看到它发生了 - 重写日志显示请求已被应用程序服务器明确接收并转发到端口8888 ...但它从来没有被node.js收到(或者至少在中间件从来没有得到它的第一行的第一行代码...)
我已经一遍又一遍我的Node.js代码,并敢肯定我没有阻挡代码,即使我这样做了,我也无法想象它会阻塞线程足够长的时间以致错过某个请求,而不会在某处引发红旗。
我错过了什么?传入的套接字是否会被阻塞?我通过我的node.js应用程序向外部API发送了相当多的HTTP请求,但AFAIK不应该阻止传入的套接字。
当然,我有错误记录到位。我已经在过程级别上启用它...
process.addListener("uncaughtException", function (err) {
// some logging code
}
和Express级别(上面的onError处理程序)。我知道我的错误日志记录功能是有效的,因为我看过他们都在之前发作。但无论他们的报告围绕着下降请求的时候什么,我也不在控制台中看到什么...
- 快递版本:3.0.0rc5
- Node.js的版本:0.8。在一个标准的亚马逊云设置(m1.large实例)运行的node.js应用程序,后面2个负载平衡器12分
- 2的情况下,连接到3×副本集MongoDBs(也m1.large)
您已确认负载均衡器正在接收请求并将其成功发送到节点服务器?当一个人失败时你多久提出一次请求? – Bill
相同的LB /应用程序服务器也提供PHP文件,永远不会造成超时。但我不太清楚如何确认LB正确转发到节点服务器,不过,除此之外。我没有出现任何交通高峰。 Rightscale上的apache日志报告一致~10 req/sec。 –
我发现了一些列出的类似问题的错误,但它们都是由0.6.6修复的。您可能会尝试升级到最新版本,因为自0.6版以来已经进行了大量修复/改进。我还建议你在你的应用服务器上设置网络嗅探器,以确保服务器实际上正在接收数据包。 – Bill