3

別の REST サービスを呼び出す REST サービスがあります。どちらも MVC 4 WebAPI を使用しており、それらを呼び出すと、負荷をかけるまで正常に動作します。簡略化されたコードは次のようなものです。

public HttpResponseMessage Get()
{
    var url = WebHelpers.CreateUrl(Request, "EmployeesGet");
    var client = new HttpClient();
    var response = client.GetAsync(url).Result;
    var retResp = new HttpResponseMessage();
    retResp.Content = response.Content;
    return retResp;
}

WebHelper.CreateUrl、エンドポイント URL を構築します。負荷をかけると、100 人のユーザーがシミュレートされ、約 16,000 のリクエストが発生し、ソケット例外が発生します。

SocketException システムに十分なバッファ領域がなかったか、キューがいっぱいだったため、ソケットに対する操作を実行できませんでした

これにより、IIS をリセットするまで PC のネットワーク スタックが停止します。後片付けをもっと積極的に行う必要があるのではないかと思い、HttpClient効果なしで処分しました。次に、エンドポイントから取得した応答を破棄する必要があると考えました。コンテンツを取得したら、もう必要ないからです。奇妙なことに、破棄されたオブジェクトを参照できないという例外が発生します。これは MVC フレームワークから来ています。例外は次のとおりです。

[ObjectDisposedException: 破棄されたオブジェクトにアクセスできません。オブジェクト名: 'System.Net.Http.StreamContent'.] System.Web.Http.WebHost.HttpControllerHandler.EndProcessRequest(IAsyncResult 結果) +49019 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +469 System.Web.HttpApplication.ExecuteStep(IExecutionStep ステップ、ブール値 & 完了した同期) +375

ストリームまたはコンテンツだけを返すと問題なく動作しますが、応答のステータス コードを変更したり、他のメタデータを応答に追加したりすることはできません。

では、REST サービスへの別の呼び出しからコンテンツを受け取った Get メソッドから応答を返す最良の方法は何でしょうか。私は逆シリアル化/シリアル化したくありません。送信される応答にデータを追加できるようにしたいと思っています。

更新:負荷テストの実行中にリソース モニターを見ていると、接続が積み重なっているのがわかります。確かなことは言えませんが、内部からのエンドポイントへの呼び出しがGet()接続を解放していないようです。

4

2 に答える 2

2

事前に作成された HttpClient インスタンスをコントローラーに挿入し、それを複数のリクエストで再利用することをお勧めします。HttpClient が破棄されると、オフになり、基になる接続を閉じようとします。HttpClient ソースを見たときのことを思い出すと、新しい HttpClient インスタンスを作成するたびに新しい接続を開くことになります。

于 2012-06-02T03:19:45.870 に答える
1

いくつかのこと

  1. .Resultスレッドをブロックする呼び出しを行っています。これは、パフォーマンスの問題の一部である可能性があります。非同期操作を実行しているためTask<HttpResponseMessage>、内部サービス呼び出しの結果を外部呼び出しの本体に変換する継続を返してスケジュールすることにより、アクション メソッドを非同期にする必要があります。
  2. HttpContent内部呼び出しの を外部呼び出しの結果に単純にコピーすることについてはわかりません。内部ストリームを読み取って、それを新しい外部ストリームにコピーしてみることをお勧めします。
于 2012-06-01T16:30:09.347 に答える