簡體   English   中英

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

Node.js請求長時間的HTTP請求時,Node.js的正確行為是什么? 情況是,我的node.js服務器的行為就像客戶端和db層(由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() }

請幫我。 如果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方法調用的每次調用創建一個新的代理實例(新的池)。 未設置maxsockets的默認agentInstance的默認值為5。

您可以按照http.globalAgent.maxSockets = Infinity的方式增加全局代理的大小,也可以根據需要增加高值,然后刪除已創建的自定義池

要么

在全局級別定義自定義池並設置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方法提供回調。 例如。

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

同樣,您需要提供鏈接此模式的錯誤回調。 即)。 on("error',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");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM