2016-12-11 11 views
3

Webサイトと呼ばれるJSONおよびPOSTメソッドに基づくWCF Webサービスがあります。この関数は、単純なコードを持っているだけで怒鳴るのコードを使用して別のWebサービスを呼び出します。問題が大きいことを、私はIISで見ることができるということですIISでホストされているWCFには多くの要求があり、サービスは遅くなります

class MyWebClient : WebClient 
     { 
      protected override WebRequest GetWebRequest(Uri address) 
      { 
       WebRequest request = base.GetWebRequest(address); 
       if (request is HttpWebRequest) 
       { 
        (request as HttpWebRequest).KeepAlive = true;      
        (request as HttpWebRequest).ContentType = "application/json"; 
       } 
       return request; 
      } 
     } 

 using (var cli = new MyWebClient()) 
     {     
      Task<string> t = cli.UploadStringTaskAsync(myURI, "POST", request); 
      if (t == await Task.WhenAny(t, Task.Delay(400))) 
      { 
       response = t.Result; 
      } 
      else 
      { 
       response = ""; 
      } 
      cli.Dispose(); 
     } 

MyWebClientクラスは次のように実装されています要求の数は、私のワーカープロセスの18秒以上、さらには1〜2時間開いています(そのうちの1つの添付イメージで確認できます)。そして、これはサービスを非常に遅くします。このサービスには1秒あたり約2Kリクエストがあり、このサービスのアプリケーションプールには12のワーカープロセスを含むWebガーデンがあり、キューの制限は10Kです。このような状況が存在し、予測可能な時間で働いて4つのワーカープロセス(約450ミリ秒)(例えば)であり、IISはその要求の最大経過時間は約380

a large number of requests that remain open in the IIS

注意であることを示しているときに起こること私はcli.UploadStringTaskAsyncを使用しており、従ってタイムアウトはcliのために考慮されません。だから、タイムアウトをシミュレートするためにt == await Task.WhenAny(t, Task.Delay(400))のようなコードを実装する必要があります。

何が問題だと思いますか? awaitを使用すると多くのコンテキストスイッチが発生し、要求はCPUによって実行されるようにキューに入れられますか?


編集:

Hereあなたが役に立ついくつかの勧告を見つけることができますが、誰も助けていないと問題を解決することができます。私はアプリケーションのWeb設定でそれらを設定しましたが、問題を解決できませんでした。


更新:追加情報として

は、ネットワークカードが1Gであることに注意して、最大で我々は100Mgb/sの帯域幅の使用を持っています。 Intel Xeon E5-1650 V3 3.5 GHzの6つのコアと12の論理プロセッサがあります。私たちは128GBのRAMと480GBのSSDを持っています。

答えて

2

問題を解決する解決策が見つかりました。重要なポイントは「processModel要素(ASP.NET設定スキーマ)」でした。

この状況は、(たとえば)4つのワーカープロセスが予測可能な時間(約450ms)で動作し、IISが要求の最大経過時間が約であることを示している場合に発生します380.

私はワーカープロセス間の負荷のバランスをとることが問題になると思います。 processModel Elementを手動で設定することで、問題を解決しました。私は多くを研究した後、this processModel要素とそのプロパティに関する貴重なリンクを発見しました。

また、thisリンクは、各項目のすべての特性と効果を説明しています。このリンクで述べたように「requestLimit」と「requestQueueLimit」と呼ばれる2重要な特性があります。

はrequestQueueLimit:ASP.NETは、「503メッセージを返す始まる前にキューで許可されている要求の数を指定します。 - サーバーの使用量が多すぎます "というメッセージが表示されます。既定値は5000です。

requestLimit:ASP.NETが新しいワーカープロセスを自動的に起動して現在のプロセスを実行する前に許可される要求の数を指定します。デフォルトは無限です。

溶液は私の場合の一例300のための合理的な数でrequestLimitを制御し、制限することです。また、ワーカープロセス数とrequestLimitを掛け合わせて、requestQueueLimitに制限します。私はワーカープロセスの数を20に増やしました。この構成では、6000リクエストは完全にキューに入れることができ、各ワーカープロセスには最大300リクエストがあります。ワーカープロセスあたり300リクエストに達すると、ASP.NETは新しいワーカープロセスを自動的に起動して、現在のプロセスを代行します。

したがって、負荷はワーカープロセス間でよりバランスが取れています。私はすべてのキューをチェックしており、400回以上経過したリクエストはありません!!!

私は、このソリューションは、(労働者のrequestLimitrequestQueueLimit数がを処理)これらのプロパティと一緒に遊んでIISワーカープロセスのための半ロードバランサアルゴリズムとして使用することができると思い。

関連する問題