当Node.js为其他服务器请求长时间的http请求时,Node.js的正确行为是什么 [英] What is the correct behavior for Node.js while Node.js is requesting a long time http request for other servers

查看:48
本文介绍了当Node.js为其他服务器请求长时间的http请求时,Node.js的正确行为是什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

what is the correct behavior for Node.js while Node.js is requesting a long time http request. The situation is that, my node.js server acts just like a web proxy between client side and db layer(which is exposed by web service). The client will send many requests to Node.js at the same time, the node.js will use request.js pass the requests to the web service. Some of the web services need seconds to get response. Because the handler of response is using callback way in request.js, it should be pushed into the event loop, and the node.js should move to hand over the new request and won't wait for the response. But in my application, the node.js won't process the new request until get the previous response. I am not sure which one is the correct behavior. For the request.js, I have added a agent in option to avoid blocked by default socket. var requestObj = { url : targetUrl, json : true, pool: new http.Agent() }

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

Please help me on this. If the node.js won't process request until get response, I can't see the reason to use node.js, so I think the issue is caused by my incorrect code. Below are the class to send http request.

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;
	}
}

已更新:
当前流程

Updated: Current process

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方法的每次调用创建新的代理程序实例(新池)调用。没有设置maxsockets的默认agentInstance将使用5作为其默认值。

You are creating a new agent instance (a new pool) for every invocation of requestAPI method invocation . A default agentInstance with no maxsockets set will have 5 as its default value.

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

You could either increase the size of the global agent as in http.globalAgent.maxSockets = Infinity or a high value depending on your reqs and remove the custom pool you have created

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

define the custom pool at the global level and set the maxsockets

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

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

Then use this variable inside your method

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

更新

正在处理请求。我来到了实现之后。
如果要在请求模块上调用http方法,则需要使用on方法提供回调。
例如。 )

On playing around with request.js i came to following realization . If you are calling http methods on request module, the callbacks need to be provided using the on method. eg. )

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

同样,您需要提供链接此模式的错误回调。 ie。)。 on(error',cb) etc

Similarly you would need to provide error callbacks chaining this pattern. ie.) .on("error',cb) etc

这将为您提供预期的行为。

This will give you the expected behavior.

更新:

我测试了以下代码,对您的版本进行了小调整任何代理。这清楚地记录了呼叫,当所有呼叫都完成时,log
s回调

I tested the following code, minor tweaks of your version without any proxies. This clearly logs the calls and when all the calls are finished log s the callbacks

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为其他服务器请求长时间的http请求时,Node.js的正确行为是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆