HttpWebRequestクラスでハマったこと

お久しぶりです。

10月になって新環境で奮闘中です。
若干サボり気味でしたが、今後はちゃんと更新していきます…。

で、今回は前職でとあるWebサービスに対して負荷検証を行ったときに、
ハマったことと解決策を書いていきます。

やりたいこと

コンソールアプリケーションで以下のような処理を複数スレッドで実行して、
レスポンスが返ってくるまでの時間を計測します。

' リクエストで投げるデータをバイト変換
Dim postData As String = "POSTする値"
Dim postDataBytes As Byte() = Encoding.UTF8.GetBytes(postData)

' リクエストクラスの生成・設定
Dim request As HttpWebRequest = WebRequest.Create("リクエストを投げるURL")
With request
    .Method = "POST"
    .ContentType = "application/x-www-form-urlencoded"
    .ContentLength = postDataBytes.Length
End With

' リクエストクラスにバイト変換したデータを書き込む
Using stream As Stream = request.GetRequestStream
    With stream
        .Write(postDataBytes, 0, postDataBytes.Length)
        .Close()
    End With
End Using

' 時間計測開始
Dim sw As New Stopwatch
sw.Start()

' レスポンスを取得
Using response As WebResponse = request.GetResponse
    ' 時間計測終了
    sw.Stop()
    ' 処理時間を出力
    Console.Write(String.Format("{0}秒かかりました。", sw.ElapsedMilliseconds * 1000))
End Using

ハマったこと

①リクエストがなぜか2本ずつしか飛ばない

処理結果を見たときに2スレッドごとに数秒間隔があいてリクエストが飛ばされてました。
そこでコマンドプロンプトを立ち上げ、 netstat -a と入力して調べたところ、
2本ずつしか通信が行われていませんでした。

※よくよくデバッグで調べたところ、上記ソースの16行目で後続処理が止まるようです。

②各スレッドの初回リクエストを投げるときに時間がかかる

実施した負荷検証では上記のソースを1スレッドで数回行ったのですが、
初回の処理だけ5秒近く多く時間がかかっていました。

解決策

Google先生に聞いてみたところ、原因と解決策が載っていました。

①リクエストがなぜか2本ずつしか飛ばない

Asynchronous HTTPWebRequest, Maximum Connections – Best Approach – Threads or Delegates?

上記のリンク先に色々書いてありますが、
私の場合はServicePointManagerクラスのDefaultConnectionLimitプロパティの値を変えることで解決しました。

ServicePointManager.DefaultConnectionLimit プロパティ

既定値が2だったため、2本ずつしかリクエストが飛ばなかったようです。

ServicePointManager.DefaultConnectionLimit = (スレッド数)

と言う風にしておけば大丈夫でしょう。

②各スレッドの初回リクエストを投げるときに時間がかかる

.NET/WebRequestが初回実行時のみ遅い

プロキシ設定のようです。

HttpWebRequest.Proxy プロパティ

Dim request As HttpWebRequest = WebRequest.Create("リクエストを投げるURL")
With request
    .Method = "POST"
    .ContentType = "application/x-www-form-urlencoded"
    .ContentLength = postDataBytes.Length
    .Proxy = Nothing
End With

上記の6行目の設定を追加して解決しました。

ただこの初回時の処理が遅いと言うのは社内ネットワークから行った時のみで、
Windows Azure上に構築した仮想マシンからでは何ら問題はありませんでした。

※ネットワーク謎~。

まとめ

普段ASP.NETでWebアプリを開発してる上では特に使ったことない処理だったんですが、
今後バッチとかで使う機会がありそうなので備忘録として残しておきます。

同じことでハマった人に少しでも助けになれば良いです。

カテゴリー: .NET, VB パーマリンク

HttpWebRequestクラスでハマったこと への1件のフィードバック

  1. モンクレール メンズ のコメント:

    It抯 exhausting to seek out knowledgeable people on this matter, but you sound like you know what you抮e talking about! Thanks

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>