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

Javascript 当Node.js为其他服务器请求长时间http请求时,Node.js的正确行为是什么,javascript,node.js,Javascript,Node.js,Node.js请求长时间http请求时,Node.js的正确行为是什么。 情况是,my node.js服务器就像客户端和数据库层(由web服务公开)之间的web代理。客户端将同时向Node.js发送多个请求,Node.js将使用request.js将请求传递给web服务。一些web服务需要几秒钟才能获得响应。因为response的处理程序在request.js中使用回调方式,所以应该将其推送到事件循环中,node.js应该移动以移交新的请求,而不会等待响应。但是在我的应用程序中,node.js在

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

请帮我做这个。如果node.js在得到响应之前不会处理请求,我看不出使用node.js的原因,因此我认为问题是由我的错误代码造成的。下面是发送http请求的类

var request=require('request');
var http=require('http');
函数apiService(){}
apiService.prototype.get=函数(上下文、有效负载、回调、url){
返回这个.requestAPI(上下文、负载、回调、url,“GET”);
}
apiService.prototype.post=函数(上下文、有效负载、回调、url){
返回这个.requestAPI(上下文、有效负载、回调、url、“POST”);
}
apiService.prototype.del=函数(上下文、有效负载、回调、url){
返回此.requestAPI(上下文、有效负载、回调、url,“删除”);
}
apiService.prototype.requestAPI=函数(上下文、有效负载、回调、url、方法){
var config=context.config;
var targetUrl=config.APIHost
+(config.port==null?”:(“:”+config.port))
+ "/" 
+config.baseDir
+ "/"
+网址;
var requestObj={
url:targetUrl,
是的,
池:新的http.Agent()
}
如果(config.proxy!=null){
requestObj.proxy=config.proxy;
}
开关(方法){
案例“职位”:
requestObj.body=有效载荷;
request.post(requestObj,函数(err,resp,body){
如果(错误){
回调(err);
返回;
}
回调(null,body);
});
打破
案例“GET”:
var queryString=“”;
用于(有效载荷中的att){
如果(查询字符串!=“”)
查询字符串+=“&”;
queryString+=att.toString()+“=”+有效负载[att];
}
如果(查询字符串!=“”)
requestObj.url+=“?”+查询字符串;
get(requestObj,函数(err,resp,body){
如果(错误){
回调(err);
返回;
}
回调(null,body);
});
打破
案例“删除”:
requestObj.body=有效载荷;
del(requestObj,函数(err,resp,body){
如果(错误){
回调(err);
返回;
}
回调(null,body);
});
打破
}

}
您正在为requestAPI方法调用的每次调用创建一个新的代理实例(一个新池)。未设置maxsockets的默认agentInstance的默认值为5

您可以增加全局代理的大小,如中所示
http.globalAgent.maxSockets
=无限大或高值,具体取决于您的需求,并删除您创建的自定义池

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

var myAPIPool = new http.Agent({"maxSockets" : Infinity}); // Infinity or a high value depending on your res.
然后在方法中使用这个变量

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

在使用request.js时,我实现了以下目标。 如果您在请求模块上调用http方法,则需要使用on方法提供回调。 例如)

类似地,您需要提供链接此模式的错误回调。例如,
打开(“错误”,cb)

这将为您提供预期的行为

更新:

我测试了下面的代码,在没有任何代理的情况下对您的版本进行了一些小的调整。这将清楚地记录调用以及所有调用完成后的日志 什么是回调

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");

非常感谢您的回复。我当前的问题不是池的大小。我当前的问题是所有node.js在收到之前的响应之前不会转发新请求。如果是池大小的问题,node.js将至少发送5个请求,但目前只有一个。谢谢。您能告诉我您的应用程序的行为吗?Thanks。我尝试过使用on方法。它仍然不起作用。你有没有没有没有这种问题的示例代码。我可以尝试确保这不是我的测试方法的问题。非常感谢你,但它与我遇到的有点不同。我遇到的是客户端向节点发送请求,节点移交给后端web服务。节点在得到最后一个请求的响应之前不会响应新的客户端请求。根据我的调试,代码可以在apiService.post之后进行检查,它只是在得到响应之后等待并响应新的请求。从什么信息推断节点在第一个请求完成之前不会处理第二个请求?什么是您的后端吗?如果您的后端不是为同时处理多个请求而构建的,那么在完成处理第一个请求之前,您的后端甚至不会记录它收到了第二个请求。
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");