どこかで何らかのリークがあるような気がしますが、特定またはトラブルシューティングの方法がわかりません。Express と nodejs の request モジュールを使用しています。負荷がかかると、Facebook Graph API へのリクエストによって行われた https 呼び出しで、長い遅延が発生したり、完全にタイムアウトしたりします。最初は受信側 (Facebook) のスロットリングの問題だと思っていましたが、同じ URL を数百回呼び出す単純な C# コンソール アプリケーションを作成すると、応答時間が 150 ミリ秒を超えることはありません。ただし、ノード内の同じコードは、50 ミリ秒から最大 10 秒まで変化します。リクエストの使用時にタイムアウト プロパティを設定すると、ESOCKETTIMEDOUT エラーが発生し始めます。リクエスト オプションで pool.maxsize を 100 に設定すると、代わりに ETIMEDOUT エラーが発生します。
ハングアップが発生している場所を特定するにはどうすればよいですか?
request モジュールの使用例を次に示します。私も自分のアプリにこれを追加しようとしました:
require('http').globalAgent.maxSockets = Infinity;
require('https').globalAgent.maxSockets = Infinity;
var executeGetUrl = function getUrl(url, cacheKey, parseJson, accessToken, callback) {
if (accessToken) {
url = url + '?access_token=' + accessToken;
}
try {
request({url: url, timeout: 10000, 'pool.maxSockets' : 100}, function (err, res, body) {
if (err) {
logger.error('Made facebook api call to ' + url + ' with error ' + err);
callback(err, null);
return;
}
if (parseJson) {
try {
body = JSON.parse(body);
} catch (err) {
callback(new Error('Could not parse ' + res.body + ': ' + err), null);
return;
}
if (body.error) {
err = new Error('Error calling ' + url + '. ' + body.error.message);
err.code = body.error.code;
callback(err, null);
}
else {
callback(null, body || {});
}
} else {
if (res.statusCode != 200) {
callback(new Error(res.body));
} else {
callback(null, res.body || {});
}
}
});
} catch (err) {
callback(null, err);
}
};
60秒間結果をメモしていますが、それは問題とは関係がないようです
var getUrl = memoize(executeGetUrl, {async: true, maxAge: 60000, length: 2});
そして、プロミスチェーンで関数を使用する
var deferred = q.defer();
getUrl(photosUrl, null, false, null, function (err, body) {
if (err) {
deferred.reject(err);
return;
}
deferred.resolve(body);
});
return deferred.promise;