IISには、トラフィックの少ないWebサイト向けの迷惑な機能があり、未使用のワーカープロセスをリサイクルするため、しばらくすると最初のユーザーが非常に長い遅延(30秒以上)になります。
私は問題の解決策を探していましたが、これらの潜在的な解決策を見つけました。
C. アイドルタイムアウトを無効にする(IIS Resetの下)
D. サイトのプリコンパイル
私はこれらのどれが好まれているのか疑問に思っています、そしてもっと重要なのは、なぜ同じ問題に対する多くの解決策があるのですか? (私の推測ではそうではなく、何かを正しく理解していないだけです)。
編集
Cを実行することで、サイトを暖かく保つのに十分なようですが、サイトの遅さの本当の原因は、エンティティフレームワーク。なぜ寒くなっているのかわかりません。 this questionを参照してください。 残念ながらまだ回答されていません 回答済みです!
私は最終的に warm up script を作成するだけで、時々サイトにアクセスして、スピーディな状態を保つことができました。
オプションA、B、およびDは、最初の開始時間にのみ影響するため、同じカテゴリにあるように見えます。これらは、メモリ内のライブラリのコンパイルやロードなどのWebサイトのウォームアップを行います。
Cを使用して、アイドルタイムアウトを設定するだけで、サーバーへの後続の要求が高速に処理されるようになります(アプリプールの再起動にはかなりの時間がかかります-秒単位)。
私の知る限り、タイムアウトは、そのマシンで並行して実行されている他のWebサイトが必要とする可能性のあるメモリを節約するために存在します。その代価は、その一回の遅いロード時間です。
ユーザーが非アクティブの場合にアプリプールがシャットダウンするという事実に加えて、アプリプールは既定で1740分(29時間)ごとにリサイクルされます。
テクネットから:
インターネットインフォメーションサービス(IIS)アプリケーションプールを定期的にリサイクルして、アプリケーションのクラッシュ、ハング、またはメモリリークを引き起こす可能性のある不安定な状態を回避できます。
アプリプールのリサイクルがオンになっている限り、それで十分です。ただし、ほとんどのコンポーネントで最高のパフォーマンスが本当に必要な場合は、前述のアプリケーション初期化モジュールなども使用する必要があります。
ウェブホスティングチャレンジ
多くの私たち(中小企業や個人)がそうであるように、共有サーバーでホストされている場合、どのマシン構成オプションも使用できないことに注意する必要があります。
ASP.NET MVCオーバーヘッド
私のサイトは、20分以上ヒットしなかった(そしてWebアプリが停止した)場合、少なくとも30秒かかります。ひどいです。
パフォーマンスをテストする別の方法
ASP.NET MVCの起動かどうかをテストする別の方法があります。通常のHTMLページをサイトにドロップして、直接アクセスできます。
問題がASP.NET MVCの起動に関連している場合、Webアプリが起動されていなくても、HTMLページはほぼ即座にレンダリングされます。
それが、問題がASP.NET MVCの起動にあることを最初に認識した方法です。いつでもHTMLページをロードすると、非常に高速にロードされます。次に、そのHTMLページにアクセスした後、ASP.NET MVC URLの1つにアクセスすると、Chromeメッセージ "Waiting for raddev.us ..."が表示されます。
有用なスクリプトを使用した別のテスト
その後、8分ごとに(アプリがアンロードする時間よりも短い時間に)WebサイトにアクセスするLINQPad(詳細は http://linqpad.net をご覧ください)スクリプトを作成しました。 20分になります)、何時間も実行させます。
スクリプトの実行中にWebサイトにアクセスし、サイトが非常に高速に起動するたびにヒットしました。これは、ASP.NET MVCの起動時間が原因である可能性が最も高いと考えられることを示しています。
LinqPadを入手すると、次のスクリプトを実行できます。URLを自分のものに変更して実行するだけで、簡単にテストできます。がんばろう。
NOTE:LinqPadでは、F4を押してSystemへの参照を追加する必要があります。あなたのページを取得するライブラリを追加するネット。
また:ASP.NET MVCサイトからルートをロードするURLを指すようにString URL変数を変更して、エンジンが実行されます。
System.Timers.Timer webKeepAlive = new System.Timers.Timer();
Int64 counter = 0;
void Main()
{
webKeepAlive.Interval = 5000;
webKeepAlive.Elapsed += WebKeepAlive_Elapsed;
webKeepAlive.Start();
}
private void WebKeepAlive_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
webKeepAlive.Stop();
try
{
// ONLY the first time it retrieves the content it will print the string
String finalHtml = GetWebContent();
if (counter < 1)
{
Console.WriteLine(finalHtml);
}
counter++;
}
finally
{
webKeepAlive.Interval = 480000; // every 8 minutes
webKeepAlive.Start();
}
}
public String GetWebContent()
{
try
{
String URL = "http://YOURURL.COM";
WebRequest request = WebRequest.Create(URL);
WebResponse response = request.GetResponse();
Stream data = response.GetResponseStream();
string html = String.Empty;
using (StreamReader sr = new StreamReader(data))
{
html = sr.ReadToEnd();
}
Console.WriteLine (String.Format("{0} : success",DateTime.Now));
return html;
}
catch (Exception ex)
{
Console.WriteLine (String.Format("{0} -- GetWebContent() : {1}",DateTime.Now,ex.Message));
return "fail";
}
}
アイドル状態のWebサイトにアクセスするためのpingサービス/スクリプトを作成することは、完全に制御できるため、むしろ最適な方法です。あなたが言及した他のオプションは、専用のホスティングボックスをリースしている場合に利用できます。
共有ホスティングスペースでは、ウォームアップスクリプトが最高の第1レベルの防御です(セルフヘルプが最高のヘルプです)。 独自のWebアプリケーションからそれを行う方法に関するアイデア を共有する記事があります。
Bを使用します。これは、ワーカープロセスのリサイクルと併せて、リサイクル中に遅延が発生するだけだからです。これにより、アイドル後の最初の要求への応答での初期化に通常関連する遅延が回避されます。また、リサイクルの利点を維持することができます。
スケジュールに基づいてサイトにpingを送信するための適切なオプションは、Microsoft Flowを使用することです。これは、1か月あたり最大750回の「実行」が無料です。サイトを1時間ごとにヒットさせて保温するフローを作成するのは非常に簡単です。サイトの複数のヒットを分離する遅延を持つ単一のフローを作成することで、750の制限を回避することもできます。
パフォーマンスの問題を解決する方法に関するヒントについては、この記事を参照してください。これには、「コールドスタート」セクションの起動に関連する両方のパフォーマンスの問題が含まれます。このほとんどは、ローカルまたは実稼働で使用しているサーバーの種類に関係なく重要です。
アプリケーションがXML(およびWebサービスを含む)から何かをデシリアライズする場合、SGENが非シリアル化に関係するすべてのバイナリに対して実行されることを確認し、結果のDLLをグローバルアセンブリキャッシュ(GAC)に配置します。これにより、SGENに対して実行されたアセンブリで使用されるすべてのシリアル化オブジェクトがプリコンパイルされ、結果のDLLにキャッシュされます。これにより、ディスクからの構成ファイルの最初のデシリアライゼーション(ロード)およびWebサービスへの最初の呼び出しにかかる時間を大幅に節約できます。 http://msdn.Microsoft.com/en-us/library/bk3w6240(VS.80).aspx
IISサーバーにインターネットへの発信アクセス権がない場合は、machine.configにgeneratePublisherEvidence =” false”を追加して、Authenticodeバイナリの証明書失効リスト(CRL)チェックをオフにします。そうしないと、すべてのワーカープロセスが起動時に20秒以上ハングし、CRLリストを取得するためにインターネットに接続しようとしてタイムアウトする可能性があります。 http://blogs.msdn.com/amolravande/archive/2008/07/20/startup-performance-disable-the-generatepublisherevidence-property.aspx
http://msdn.Microsoft.com/en-us/library/bb629393.aspx
すべてのアセンブリでNGENを使用することを検討してください。ただし、慎重に使用しないと、パフォーマンスはそれほど向上しません。これは、各プロセスによってロードされるすべてのバイナリのベースロードアドレスが、重複しないようにビルド時に慎重に設定する必要があるためです。アドレスの競合が原因でロード時にバイナリをリベースする必要がある場合、NGENを使用することによるパフォーマンスの向上はほとんど失われます。 http://msdn.Microsoft.com/en-us/magazine/cc163610.aspx
4分間何も操作しないと、最初の要求で一貫して15秒の遅延が発生していました。問題は、アプリがSQL ServerへのWindows統合認証を使用しており、サービスプロファイルがサーバーとは異なるドメインにあったことです。これにより、アプリの初期化時にIISからSQLへのクロスドメイン認証が発生しました。これが実際の遅延の原因でした。 Windows認証の代わりにSQLログインを使用するように変更しました。遅延はすぐになくなりました。パフォーマンスを向上させるために、すべてのアプリ初期化設定がまだありますが、私の場合はまったく必要ありませんでした。