C# で記述された ASP.NET 3.5 サーバー アプリケーションがあります。HttpWebRequest と HttpWebResponse を使用して、REST API への送信要求を行います。
これらのリクエストを別々のスレッドで送信するテスト アプリケーションをセットアップしました (サーバーに対する並行性をぼんやりと模倣するため)。
これは、コードに関する質問というよりも、Mono/Environment に関する質問であることに注意してください。したがって、以下のコードは逐語的ではないことに注意してください。機能ビットのカット/ペーストだけです。
ここにいくつかの疑似コードがあります:
// threaded client piece
int numThreads = 1;
ManualResetEvent doneEvent;
using (doneEvent = new ManualResetEvent(false))
{
for (int i = 0; i < numThreads; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Test), random_url_to_same_host);
}
doneEvent.WaitOne();
}
void Test(object some_url)
{
// setup service point here just to show what config settings Im using
ServicePoint lgsp = ServicePointManager.FindServicePoint(new Uri(some_url.ToString()));
// set these to optimal for MONO and .NET
lgsp.Expect100Continue = false;
lgsp.ConnectionLimit = 100;
lgsp.UseNagleAlgorithm = true;
lgsp.MaxIdleTime = 100000;
_request = (HttpWebRequest)WebRequest.Create(some_url);
using (HttpWebResponse _response = (HttpWebResponse)_request.GetResponse())
{
// do stuff
} // releases the response object
// close out threading stuff
if (Interlocked.Decrement(ref numThreads) == 0)
{
doneEvent.Set();
}
}
Visual Studio Web サーバーのローカル開発マシン (Windows 7) でアプリケーションを実行すると、numThreads を上げて、1 人の「ユーザー」でも 100 人でも、最小限の変動で同じ平均応答時間を得ることができます。
Mono 2.10.2 環境でアプリケーションを Apache2 に公開およびデプロイすると、応答時間はほぼ直線的に変化します。(つまり、1 スレッド = 300 ミリ秒、5 スレッド = 1500 ミリ秒、10 スレッド = 3000 ミリ秒)。これは、サーバー エンドポイント (異なるホスト名、異なるネットワークなど) に関係なく発生します。
IPTRAF (およびその他のネットワーク ツール) を使用すると、アプリケーションがすべての接続をルーティングするために 1 つまたは 2 つのポートのみを開き、残りの応答を待機する必要があるように見えます。
同様の PHP アプリケーションを構築し、同じリクエストを使用して Mono にデプロイしました。レスポンスは適切にスケーリングされます。
Mono と Apache で考えられるすべての構成設定を実行しましたが、2 つの環境間で (少なくともコードで) 唯一異なる設定は、Mono では ServicePoint SupportsPipelining=false であり、私の環境では true である場合があることです。機械。
何らかの理由で ConnectionLimit (デフォルトの 2) が Mono で変更されていないようですが、指定されたホストのコードと web.config の両方でより高い値に設定しています。
私と私のチームが重要なことを見落としているか、これが Mono の何らかのバグであるかのどちらかです。