2012-01-09 17 views
1

私はASP.NET 3.5を使用してWebサイトを構築しています。ウェブサイトの1つの領域には、他のウェブサーバでホストされているjpegの28個のビデオサムネイル画像が表示されます。これらのjpegが1つ以上存在しない場合は、ブラウザの画像リンクが壊れているのではなく、ローカルにホストされているデフォルトの画像をユーザに表示します。HTTP HEADリクエストでタイムアウトが不明な理由

私がこれを実装するために取ったアプローチは、ページがレンダリングされるたびに、それぞれのイメージに対してHTTP HEAD要求を実行することです。 200 OKステータスコードが返ってきたら、イメージは良好で、<img src="http://media.server.com/media/123456789.jpg" />を書き出すことができます。 404が見つからない場合は、<img src="/images/defaultthumb.jpg" />を書き出します。

もちろん、すべてのリクエストに対して毎回これを行う必要はないので、アプリケーションレベルでキャッシュされたイメージステータスオブジェクトのリストを実装して、各イメージが5分ごとに1回だけチェックされるようにしましたしかし、これは実際に私の問題に関係していません。

これは非常にうまくいくようです。私の問題は、特定のイメージでは、HTTP HEAD要求がRequest Timed Outで失敗することです。

タイムアウト値を200msに非常に低く設定しているため、ページのレンダリングが遅すぎることはありません。このタイムアウトはほとんどの画像でうまくいくようですが、私はデバッグ中にこれをやり直してみましたが、10秒以上でも違いはありません。

私が起こっていただきました!見にログファイルを書き出し、これは私が(明確にし、匿名性のために編集)得るものです:

14:24:56.799|DEBUG|[HTTP HEAD CHECK OK [http://media.server.com/adpm/505C3080-EB4F-6CAE-60F8-B97F77A43A47/videothumb.jpg]] 
14:24:57.356|DEBUG|[HTTP HEAD CHECK OK [http://media.server.com/adpm/66E2C916-EEB1-21D9-E7CB-08307CEF0C10/videothumb.jpg]] 
14:24:57.914|DEBUG|[HTTP HEAD CHECK OK [http://media.server.com/adpm/905C3D99-C530-46D1-6B2B-63812680A884/videothumb.jpg]] 
... 
14:24:58.470|DEBUG|[HTTP HEAD CHECK OK [http://media.server.com/adpm/1CE0B04D-114A-911F-3833-D9E66FDF671F/videothumb.jpg]] 
14:24:59.027|DEBUG|[HTTP HEAD CHECK OK [http://media.server.com/adpm/C3D7B5D7-85F2-BF12-E32E-368C1CB45F93/videothumb.jpg]] 
14:25:11.852|ERROR|[HTTP HEAD CHECK ERROR [http://media.server.com/adpm/BED71AD0-2FA5-EA54-0B03-03D139E9242E/videothumb.jpg]] The operation has timed out 
Source: System 
Target Site: System.Net.WebResponse GetResponse() 
Stack Trace: at System.Net.HttpWebRequest.GetResponse() 
    at MyProject.ApplicationCacheManager.ImageExists(String ImageURL, Boolean UseCache) in d:\Development\MyProject\trunk\src\Web\App_Code\Common\ApplicationCacheManager.cs:line 62 

14:25:12.565|ERROR|[HTTP HEAD CHECK ERROR [http://media.server.com/adpm/92399E61-81A6-E7B3-4562-21793D193528/videothumb.jpg]] The operation has timed out 
Source: System 
Target Site: System.Net.WebResponse GetResponse() 
Stack Trace: at System.Net.HttpWebRequest.GetResponse() 
    at MyProject.ApplicationCacheManager.ImageExists(String ImageURL, Boolean UseCache) in d:\Development\MyProject\trunk\src\Web\App_Code\Common\ApplicationCacheManager.cs:line 62 

14:25:13.282|ERROR|[HTTP HEAD CHECK ERROR [http://media.server.com/adpm/7728C3B6-69C8-EFAA-FC9F-DAE70E1439F9/videothumb.jpg]] The operation has timed out 
Source: System 
Target Site: System.Net.WebResponse GetResponse() 
Stack Trace: at System.Net.HttpWebRequest.GetResponse() 
    at MyProject.ApplicationCacheManager.ImageExists(String ImageURL, Boolean UseCache) in d:\Development\MyProject\trunk\src\Web\App_Code\Common\ApplicationCacheManager.cs:line 62 

あなたが見ることができるように、最初の25件のHEADリクエストが動作し、ファイナル3はしません。それは常に最後の3つです。

失敗したHEADリクエストURLの1つをウェブブラウザ:http://media.server.com/adpm/BED71AD0-2FA5-EA54-0B03-03D139E9242E/videothumb.jpgに貼り付けると、問題なくイメージがロードされます。

ここで何が起こっているのかを調べるために、私はWiresharkを使って画像をホストするWebサーバーに送信されるすべてのHTTP要求をキャプチャしました。私が与えたログの例では、成功した25個のHEADリクエストを25件見ることができますが、失敗した3個はwiresharkトレースに表示されません。

視覚内容の異なる画像を除き、画像ごとに違いはありません。

ブラウザで動作していてもURL自体の問題を解消するために、最初の画像の1つを最後に失敗した3つの画像に切り替えることで順序を変更しました。私がこれをすると、失敗してしまった問題のために問題がなくなり、リストの最後までぶつかったもののために失敗し始めます。


だから私は、私が立て続けに発生したときに25曲の以上のHEADリクエスト、その後のHEADリクエストに関係なく、特定のURLの失敗という上から推論することができると思います。また、最初の25を超えるWiresharkトレースの要求がないため、リモートイメージホスティングサーバーではなくIISサーバー上に問題があることもわかります。

HEADリクエストを実行するために使用しているコードスニペット以下に示す。誰が私に問題の可能性について何か示唆を与えることができますか?リクエストヘッダー値のさまざまな組み合わせを試しましたが、いずれも違いはありません。私の直感は、ASP.NETページへの任意の1つの要求で同時HttpWebRequestsの数を25に制限するIIS設定があることです。

 try { 
      HttpWebRequest hwr = (HttpWebRequest)WebRequest.Create(ImageURL); 
      hwr.Method = "HEAD"; 
      hwr.KeepAlive = false; 
      hwr.AllowAutoRedirect = false; 
      hwr.Accept = "image/jpeg"; 
      hwr.Timeout = 200; 
      hwr.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.Reload); 
      //hwr.Connection = "close"; 

      HttpWebResponse hwr_result = (HttpWebResponse)hwr.GetResponse(); 
      if (hwr_result.StatusCode == HttpStatusCode.OK) { 

       Diagnostics.Diags.Debug("HTTP HEAD CHECK OK [" + ImageURL + "]", HttpContext.Current.Request); 

       // EXISTENCE CONFIRMED - ADD TO CACHE 
       if (UseCache) { 
        _ImageExists.Value.RemoveAll(ie => ie.ImageURL == ImageURL); 
        _ImageExists.Value.Add(new ImageExistenceCheck() { ImageURL = ImageURL, Found = true, CacheExpiry = DateTime.Now.AddMinutes(5) }); 
       } 

       // RETURN TRUE 
       return true; 

      } else if (hwr_result.StatusCode == HttpStatusCode.NotFound) { 
       throw new WebException("404"); 
      } else { 
       throw new WebException("ERROR"); 
      }    

     } catch (WebException ex) { 
      if (ex.Message.Contains("404")) { 

       Diagnostics.Diags.Debug("HTTP HEAD CHECK NOT FOUND [" + ImageURL + "]", HttpContext.Current.Request); 

       // NON-EXISTENCE CONFIRMED - ADD TO CACHE 
       if (UseCache) { 
        _ImageExists.Value.RemoveAll(ie => ie.ImageURL == ImageURL); 
        _ImageExists.Value.Add(new ImageExistenceCheck() { ImageURL = ImageURL, Found = false, CacheExpiry = DateTime.Now.AddMinutes(5) }); 
       } 

       return false; 

      } else { 

       Diagnostics.Diags.Error(HttpContext.Current.Request, "HTTP HEAD CHECK ERROR [" + ImageURL + "]", ex); 

       // ASSUME IMAGE IS OK 
       return true; 
      } 

     } catch (Exception ex) { 
      Diagnostics.Diags.Error(HttpContext.Current.Request, "GENERAL CHECK ERROR [" + ImageURL + "]", ex); 

      // ASSUME IMAGE IS OK 
      return true; 
     } 

答えて

1

私はこれを自分で解決しました。問題は実際に許可された接続の数であり、デフォルトでは24に設定されていました。私の場合は

は、私はちょうどあなたが必要と同時接続数に ServicePointManager.DefaultConnectionLimitを設定し、 MyHttpWebRequest.ServicePoint.CurrentConnectionsが最大制限値を増やすには10未満

ある場合にのみ、画像チェックを実行するつもりです。

何人かの人が、接続が自分自身を破壊するまで待機する時間であるアイドル時間を減らすのに役立つ代替方法があります。これを変更するには、MyHttpWebRequest.ServicePoint.MaxIdleTimeをミリ秒単位のタイムアウト値に設定する必要があります。

関連する問題