3

ローカル ストレージ用の外部 Web API からデータを取得する node.js スクリプトがあります。最初のリクエストは、詳細情報を取得する必要がある ID のリストを返すクエリです。返された ID ごとに、node.js から新しい http リクエストを生成し、サーバーにアクセスしてデータを取得します (POST リクエスト)。仕事が終わったら、3分間寝て、繰り返します。ID の数が数百になることもあります。これらの個々の http 要求は、おそらく 1kb のデータを返しますが、通常はそれ以下であるため、往復は非常に短くなります。

今朝、API プロバイダーから、「何百もの接続ですべての API サーバーを占有している」ため、プロセスを停止するように頼むメールを受け取りました (これは実際にはかなり誇りに思っていますが、それは重要ではありません)。念のため、睡眠時間を 3 分から 30 分に増やしまし

質問について...今はmaxSockets何も設定していないので、デフォルトは5だと思います。一度に5つのライブHTTPリクエスト接続しか作成できないということでしょうか? 管理者はどのように数百を持っていますか? データが配信されると、サーバーは接続を切断しませんか? 私はそうしていませんか?http リクエストの最後に明示的な切断がないので、おそらくここで問題があります。maxSocketsでは、実際には何が設定されているのでしょうか。

4

1 に答える 1

4

申し訳ありませんが、あなたの質問を正しく読んでいませんでした

maxSocketsは、http モジュールが現在のプロセスに対して確立する接続の最大数です。からアクセスして、現在の設定を確認できますhttp.globalAgent.maxSockets

特定のホストへの現在の接続数に関する情報を次のように表示できます。

console.log("Active socket connections: %d", http.globalAgent.sockets['localhost:8080'].length )
console.log("Total queued requests: %d", http.globalAgent.requests['localhost:8080'].length)

リクエストlocalhost:8080を作成しているホストとポートを に置き換えます。

次の 2 つのポイントで、ノードがこれらの接続を処理する方法を確認できます。

新しい接続の追加とリクエスト キューへの格納

https://github.com/joyent/node/blob/master/lib/_http_agent.js#L83

キューに入れられたリクエストからの接続の作成

https://github.com/joyent/node/blob/master/lib/_http_agent.js#L148


これらのリクエストを少しずらす方法を説明するために、これを非常に簡単に書きました。この特定のコードは、「保留中」のリクエストの数を確認しません。簡単に変更して、特定の時間に設定された数のリクエストのみを送信できるようにすることができます(正直なところ、それを行うより良い方法です) .

var Stagger = function (data, stagger, fn, cb) {

    var self        = this;
    this.timerID    = 0;
    this.data       = [].concat(data);
    this.fn         = fn;
    this.cb         = cb;
    this.stagger    = stagger;
    this.iteration  = 0;
    this.store      = {};

    this.start = function () {
        (function __stagger() {

            self.fn(self.iteration, self.data[self.iteration], self.store);

            self.iteration++;

            if (self.iteration != self.data.length)
                self.timerID = setTimeout(__stagger, self.stagger);
            else
                cb(self.store);

        })();
    };

    this.stop = function () {
        clearTimeout(self.timerID);

    };
};


var t = new Stagger([1,2,3,4,5,6], 1000, function (i, item, store) {
    console.log(i, item);
    if (!store.out) store.out = [];

    store.out[i] = Math.pow(2,i);
},
function (store) {
    console.log('Done!', store);
});

t.start();

このコードは間違いなく改善される可能性がありますが、おそらくどこから始めればよいかがわかります。

ライブデモ: http://jsbin.com/ewoyik/1/edit (注: コンソールが必要)

于 2013-04-17T17:24:04.223 に答える