5

私のプログラムは、1 秒あたり最大 10 個のリクエストしか受け付けない Web サービスと通信しています。ときどき、私のプログラムは 100 以上の同時要求を Web サービスに送信し、プログラムがクラッシュする原因になります。

Node.js での同時リクエストを毎秒 5 に制限するにはどうすればよいですか? リクエストライブラリを使用しています。

 // IF EVENT AND SENDER
    if(data.sender[0].events && data.sender[0].events.length > 0) {


        // FIND ALL EVENTS
        for(var i = 0; i < data.sender[0].events.length; i++) {

            // IF TYPE IS "ADDED"
            if(data.sender[0].events[i].type == "added") {
                switch (data.sender[0].events[i].link.rel) {
                    case "contact" :
                        batch("added", data.sender[0].events[i].link.href);
                        //_initContacts(data.sender[0].events[i].link.href);
                        break;
                } 
            // IF TYPE IS "UPDATED"
            } else if(data.sender[0].events[i].type == "updated") {

                switch (data.sender[0].events[i].link.rel){                     
                    case "contactPresence" :
                        batch("updated", data.sender[0].events[i].link.href);
                        //_getContactPresence(data.sender[0].events[i].link.href);
                        break;
                    case "contactNote" :
                        batch("updated", data.sender[0].events[i].link.href);
                        // _getContactNote(data.sender[0].events[i].link.href);
                        break;
                    case "contactLocation" :
                        batch("updated", data.sender[0].events[i].link.href);
                        // _getContactLocation(data.sender[0].events[i].link.href);
                        break;
                    case "presenceSubscription" :
                        batch("updated", data.sender[0].events[i].link.href);
                        // _extendPresenceSubscription(data.sender[0].events[i].link.href);
                        break;
                }
            }
        };

そして、自家製のバッチメソッド:

var updated = [];
var added = [];

var batch = function(type, url){
    console.log("batch called");


    if (type === "added"){
        console.log("Added batched");
        added.push(url);
        if (added.length > 5) {
            setTimeout(added.forEach(function(req){
                _initContacts(req);
            }), 2000);
            added = [];
        }
    } 
    else if (type === "updated"){
        console.log("Updated batched");
        updated.push(url);
        console.log("Updated length is : ", updated.length);
        if (updated.length > 5){
            console.log("Over 5 updated events");
            updated.forEach(function(req){
                setTimeout(_getContactLocation(req), 2000);
            });
            updated = [];
        }
    }       
};

実際のリクエストの例:

var _getContactLocation = function(url){
    r.get(baseUrl + url, 
    { "strictSSL" : false, "headers" : { "Authorization" : "Bearer " + accessToken }}, 
        function(err, res, body){
            if(err)
                console.log(err);
            else {
                var data = JSON.parse(body);
                self.emit("data.contact", data);
            }
        }
    );
};
4

2 に答える 2

6

これはまさに、ノードのAgentクラスが対処するように設計されているものです。ばかげたことをしたり、リクエスト オプションとしてrequire('http').globalAgent.maxSockets = Number.MAX_VALUE渡したりしましたか?agent: false

Node のデフォルトの動作では、プログラムは一度に 5 つを超える同時リクエストを送信しません。さらに、エージェントは、単純なキューではできない最適化 (つまり、HTTP キープアライブ) を提供します。

多くのリクエストを作成しようとすると (たとえば、ループから 100 件のリクエストを発行する)、最初の 5 件が開始され、エージェントは残りの 95 件をキューに入れます。リクエストが完了すると、次のリクエストが開始されます。

おそらくやりたいことはAgent、Web サービス リクエスト用の を作成し、それをリクエストのすべての呼び出しに渡すことです (リクエストをグローバル エージェントに混在させるのではなく)。

var http=require('http'), svcAgent = http.Agent();

request({ ... , agent: svcAgent });
于 2013-08-19T19:43:14.090 に答える