日曜日, 5月 14, 2006

HTTPリクエストを単一サーバへ大量に投げる方法(.NET 2.0)

技術メモ。
HTTPリクエストを、単一サーバへどかどか投げる。そんなコードは書かずにすむ
なら書かへん方が良いわけやけど、そうもいかないのがプログラマの世界。
ってわけで、もしかしたら誰かの役に立つかもしれないので、最近ハマってたことをメモ書きしておく。

まず、相手サーバが単一のサーバの場合は、リクエスト自体は2つまでしか投げられへん。これは、.NETで制限がかけられてるから。これはRFCで推奨されてる。


これを回避するためには、こういうコードを一行追加すればいい。
ServicePointManager.DefaultConnectionLimit = 100

次に、ThreadPoolの問題。
HTTPWebRequestってのはどうやら内部でThreadPoolを使用しているらしく(たぶんね。未確認)、大量にリクエストを発光すると、「十分なThreadPoolがありません」などとのたまわれる。僕はそれで結構長いこと苦しんでいたわけやけど、Visual Studio 2005っていうか、.NET Framework 2.0になってから、ThreadPoolの最大起動数が簡単に変更できる関数が追加されていて、VS2003->2005へ移行し、ようやくその問題から解放された!
(一応、VS2003時点でも、Machine.configか何かの設定ファイルをいぢくることで最大ThreadPoolを変更できる)

一応書いておくと、ThreadPoolは、最大25まで起動するけど、それ以上の追加した分も破棄されるわけじゃなく、キューにため込まれて、スレッドが使えるようになり次第、次のものが起動されるので、26個目にすぐにエラーが出るわけじゃない。

さらにスレッドを使って、単一サーバにHTTPリクエストを50以上も一度に投げると、どうやら、Webサーバ側ではすぐに受け取れないらしい(サーバの設定によるのか?)。

今回、サーバ側では5秒経ったら応答を返すようなプログラムを作って置いておいたわけやけど、サーバ側のプロセスを見ていると、受け取る順番はまったくばらばらになっていて、一番初めに投げたリクエストの処理が、7秒程度も経ってから開始されたりしてた。つーわけで、応答が普通ではあり得ないほど遅れてくることがあるわけで、タイムアウトは結構長めに取っておいたほうがいい。

0 件のコメント: