node.jsのHTTPクライアントでレスポンス時間が遅延する問題を解消する
node.jsのHTTPクライアントでレスポンス時間が遅延する問題を解消する方法を紹介します。
1.問題点
業務で、Ruby on Railsを使ったシステム開発を行っています。
で、システムが一定の負荷(約200万HTTPリクエスト/時間)に耐えられるかという性能測定を行っています。
かなりおおざっぱなシーケンスですが、このシステムでは図のようにサーバ・クライアントともにHTTPリクエストを送受信する仕組みが必要です。
サーバはApache+Passenger+Rubyで構築し、クライアントはスタブおよびドライバとしてnode.jsを使っています。
で、スタブ・ドライバによる負荷の特徴として、時間の経過とともに処理すべき秒間HTTPリクエスト数が少しずつ増加していくのですが、秒間リクエスト数が一定数(おそらく数百)を超えると、クライアントから送信したリクエストのレスポンス時間が遅延するという問題が発生しました。
しかも、一旦遅延が発生すると経過時間に比例して遅延する秒数が延び、回復することがありません。グラフにすると以下のような感じです。
ちなみに正常時のレスポンス時間は数十msで、遅延が発生すると数分経った時点で10秒以上になります。
サーバの各製品についてパフォーマンスのチューニングを行いましたが改善されません。
2.原因と対処
node.jsに原因がありました。
具体的には、node.jsのHTTPクライアントのソケットプーリングはデフォルトで有効になっているのですが、これを無効にすることで事象が解消しました。
変更後のプログラムは下記のようなもので、options.agentに「false」を設定すればソケットプーリングを無効にできます。
var http = require('http');
var options = {
host: 'www.sample.com',
port: 80,
path: '/'
};
options.agent = false;
http.get(options, function(res) {
// ...
});
あるいはmaxSockets(デフォルト5)を増やす方法もあるようです。
maxSocketsを変更する場合、以下のように設定すればいいみたいですがこちらは動作未確認です。
var http = require('http');
http.globalAgent.maxSockets = 10;
3.参考サイト
参考サイトは以下です。ありがとうございました。
- Windows+Node.js+Socket.IO