Node.js为其他服务器请求长时间的http请求时,Node.js的正确行为是什么?

当Node.js请求长时间的http请求时,Node.js的正确行为是什么? 情况是,我的node.js服务器就像客户端和数据库层之间的Web代理(它是由Web服务公开的)。 客户端会同时向Node.js发送多个请求,node.js将使用request.js将请求传递给Web服务。 一些Web服务需要几秒钟才能得到响应。 因为响应的处理程序在request.js中使用callback方式,所以应该将其压入事件循环中,并且node.js应该移动以移交新请求,而不会等待响应。 但在我的应用程序中,node.js将不会处理新的请求,直到获得前一个响应。 我不确定哪一个是正确的行为。 对于request.js,我在选项中添加了一个代理以避免被默认套接字阻塞。 var requestObj = { url : targetUrl, json : true, pool: new http.Agent() }

请帮助我。 如果node.js在得到响应之前不会处理请求,我看不到使用node.js的原因,所以我认为这个问题是由我的不正确的代码引起的。 下面是发送http请求的类。

 var request = require('request'); var http = require('http'); function apiService(){} apiService.prototype.get = function (context, payload, callback, url){ return this.requestAPI(context, payload, callback, url, "GET"); } apiService.prototype.post = function(context, payload, callback, url){ return this.requestAPI(context, payload, callback, url, "POST"); } apiService.prototype.del = function(context, payload, callback, url){ return this.requestAPI(context, payload, callback, url, "DELETE"); } apiService.prototype.requestAPI = function(context, payload, callback, url, method){ var config = context.config; var targetUrl = config.APIHost + (config.port == null ? "": (":" + config.port)) + "/" + config.baseDir + "/" + url; var requestObj = { url : targetUrl, json : true, pool: new http.Agent() } if (config.proxy != null){ requestObj.proxy = config.proxy; } switch (method){ case "POST": requestObj.body = payload; request.post(requestObj, function (err, resp, body){ if (err){ callback(err); return; } callback(null, body); }); break; case "GET": var queryString = ""; for (att in payload){ if (queryString != "") queryString += "&"; queryString += att.toString() + "=" + payload[att]; } if (queryString!="") requestObj.url += "?" + queryString; request.get(requestObj, function (err, resp, body){ if (err){ callback(err); return; } callback(null, body); }); break; case "DELETE": requestObj.body = payload; request.del(requestObj, function (err, resp, body){ if (err){ callback(err); return; } callback(null, body); }); break; } } 

更新:当前进程

 client request1 -> Node client request2 -> Node Node server request1 ->backend Node <- server response1 backend client <- response1 Node Node server request2 ->backend Node <- server response2 backend client <- response2 Node 

我认为应该是

  client request1 -> Node client request2 -> Node Node server request1 -> backend Node server request2 -> backend Node <- server response2 backend client <-response2 Node Node <- server response1 backend client <-response1 Node 

您正在为每个requestAPI方法调用的调用创build一个新的代理实例(一个新的池)。 没有设置maxsockets的默认agentInstance将有5作为默认值。

您可以像http.globalAgent.maxSockets = Infinity一样增加全局代理的大小,也可以根据您的请求增加一个较高的值,并删除您创build的自定义池

要么

在全局级别定义自定义池并设置maxsockets

 var myAPIPool = new http.Agent({"maxSockets" : Infinity}); // Infinity or a high value depending on your res. 

然后在你的方法中使用这个variables

 var requestObj = { url : targetUrl, json : true, pool: myAPIPool } 

更新

在玩request.js我来到以下实现。 如果您在请求模块上调用http方法,则需要使用on方法提供callback。 例如。 )

  request.get(requestObj).on('response', function (response){ callback(null, body); }); 

同样,你需要提供链接这种模式的错误callback。 即)。 on("error',cb)

这会给你预期的行为。

更新:

我testing了下面的代码,在没有任何代理的情况下对你的版本进行了小小的调整。 这清楚地logging了呼叫,并且当所有呼叫完成时logging呼叫

 var request = require('request'); var http = require('http'); function apiService() {} apiService.prototype.get = function(context, payload, callback, url) { return this.requestAPI(context, payload, callback, url, "GET"); } apiService.prototype.post = function(context, payload, callback, url) { return this.requestAPI(context, payload, callback, url, "POST"); } apiService.prototype.del = function(context, payload, callback, url) { return this.requestAPI(context, payload, callback, url, "DELETE"); } apiService.prototype.requestAPI = function(context, payload, callback, url, method) { var requestObj = { url: url, json: true, pool: new http.Agent() } switch (method) { case "GET": request.get(requestObj, function(err, resp, body) { if (err) { callback(err); return; } callback(null, body); }); break; } } var apicaller = new apiService(); var url = "http://google.com"; var called = 0; var cb = function() { console.log("called once" + (called++)); } console.log("calling"); apicaller.requestAPI(null, null, cb, url, "GET"); console.log("calling"); apicaller.requestAPI(null, null, cb, url, "GET"); console.log("calling"); apicaller.requestAPI(null, null, cb, url, "GET"); console.log("calling"); apicaller.requestAPI(null, null, cb, url, "GET"); console.log("calling"); apicaller.requestAPI(null, null, cb, url, "GET");