web-dev-qa-db-ja.com

Azure Web App(ASP.NET MVC)は、10分ごとにコールドになり、ロードに+ 10〜20秒かかります

Azure Web Appで非常に奇妙な問題が発生し、非常に不満を感じています。

アプリを使用すると非常に高速で応答性が高いことがわかりますが、約10分間使用しないと、非常にコールドスタート(約10〜20秒)になります。このコールドスタートは、データベースが関係している場合にのみ発生します。 Webアプリをリリースするときと少し似ています。

私たちの試み

Azure内のApplicationInsightsを使用して、5分ごとにこのpingを設定しました。

enter image description here

外れ値は常に私のデプロイによって引き起こされます(現在デプロイメントスロットを使用していません)。ただし、このログインページはデータベースを呼び出さないため、これらのデータに「コールド」スタートは表示されません。

アプリケーションのセットアップはしっかりしている必要があります。私たちのウェブアプリは北ヨーロッパでAlways onでホストされています:

enter image description here

問題が他のアプリと絡み合っていることを確認するために、セットアップ全体を新しいリソースグループ/アプリサービスプランに移動しました。新しいアプリサービスプランはStandard 1 smallですが、これは問題にはなりません。私たちの消費を見て、私は心配していません、そしておそらく私たちの問題を解決した後に私がするより小さなサービスを試すことさえできます:

enter image description here

私たちのSQLデータベースは北ヨーロッパでもホストされています(以前にその間違いを犯したため、場所を10億回チェックしました)。

アプリサービスと同様に、「大きすぎる」ハードウェアを選択して、問題が発生していないことを確認しました(標準S0:10 DTU)。使用量は途方もなく低いです:

enter image description here

継続的デプロイ(Azureメニュー内のDeployment options)を使用しますが、デプロイメントを見ると、常に何かをデプロイするべきではありません。

enter image description here

アプリに来る欲求不満は、それが機能するときに非常に敏感です。 「ウォーム」の場合、ウェブアプリに表示される平均応答時間のように、すべてのページが数秒で読み込まれます。

enter image description here

しかし、私たち(または私たちのユーザー!)が私たちのアプリを使用するとき、これらの数字はまったく間違っています。ここでは、最初のロードが+ 10〜20秒になることがよくあります。

誰かが何か考えを持っていますか?ヒントはありますか?あなたは私がどれほど感謝するか分かりません。

編集と更新1:

さらにいくつかのテストを設定することにしました。別のページを呼び出すことで、問題を示す実際のデータを取得できました。皮肉なことに、このページはデータベースを呼び出さないので、これはデータベースの問題だと思いましたが、このようには見えません。ここでチャレンジを参照してください(トレンドは+24時間続きます)。

正確に約10秒安定しているのは奇妙です。そして、傾向は10〜20分ごとではなく、5分ごとに近いように見えます-それらの間の間隔はまったく同じです:

enter image description here

編集と更新2:

もう少し掘り下げてきました。非常に興味深い洞察がいくつかあることがわかりました。編集1からの「遅い」11秒の呼び出しは、米国東部と1つのエンドポイントからのみです( http://prntscr.com/jcv69w )、そして

私が見つけた最も興味深いものは次のとおりです。

アプリケーション自体にはキャッシュがありません。キャッシュを使用すると想定しているEntityFrameworkを使用していますが、それだけです。

アプリにログインし、Chromeでクリックしました。すでにアクセスしたページが(DBからのデータで)瞬時に表示されていることがわかりましたが、新しいページを開くと、読み込みが遅くなります。初めてページを開いたときに、一部のエンティティがキャッシュされているように見えました。

次に、新しいブラウザーでアプリを開こうとしました。以前にChromeで開いたページを開くと、すぐに開きます。以前にクリックしたことのない新しいページを開いた場合、約10秒の読み込みがあります。

私が今使用しているEntityFrameworkは、何らかの理由で問題を引き起こしていると思います。

編集3:

賞金を追加したばかりで、多くのロギングを設定しています。 MiniProfilerを追加しましたが、本番環境で機能させるのに問題があります(ローカルリクエストでのみ表示されます)。

また、Application_StartApplication_BeginRequestApplication_EndRequestのglobal.asaxにログインして、いくつかとステータスを確認することも追加しました。すぐに調査結果で更新されます。

編集4:

だから今、私は最初の興味深い数字を持っています。アプリはリサイクルされていません。 Application_Startは1回だけ呼び出されます。

EndRequestBeginRequestにログオンすると、時差がわかります。これら2つの間に+15秒以上かかる複数の呼び出しがあることがわかります...しかし、サイトが暖かい場合、ページによっては約0.5〜2秒かかります。そのため、リクエストの最初と最後の間に非常に奇妙なことが起こっています。さらにデバッグ!

編集5:

MiniProfilerが機能するようになりました。低速ロード(約15秒)の例を次に示します。

enter image description here

次のステップは、Entity Frameworkの追跡と、回線呼び出し用の回線を追加することです。私はデータベースでお金を稼いでいます!

編集6:

沖戸木、私は間違っていた。遅いのはレンダリングメソッドです-データベースではありません!これをデバッグする方法がわかりません...グーグルへ!

enter image description here

編集7:

別の更新の時間です。ステータスは次のとおりです。何も解決されていません。

だから私はたくさんのことを試しました:

1)すべての種類のキャッシュを無効にしようとしました( 属性を使用した特定のアクションのASP.NET MVCでのキャッシュを防止します )。同じ動作をします。最初のロード?スロー。次のロード?速い。 5〜10分待ちます。同じ動作なので、解決されません。

2)startup.authファイルに5分の遅延でいくつかのカスタムのものがありました。削除されました。問題ありません。

3)認証にカスタム属性を使用しました。私はそれを削除しました。

4)Entity Frameworkの実装を更新して、リクエストごとに機能するようにしました

私は本当にイライラしています。私の次のステップは:

A)同じページの5〜10バージョン(_layoutなし、レイアウトあり、データベースあり、データベースなし、依存性注入あり、これらすべてなし)を作成してみて、パターンを見つけることができるかどうかを確認してください。

B)ホスティングを仮想マシンに移動して、問題が解決するかどうかを確認してください

編集8-新しい遺物が追加されました:

NewRelicを追加しました。 2つの非常に恐ろしいことが次のとおりです(エラーを見つけて再現しました!):

enter image description here

そしてフロントエンドに関しては(New Relicのブラウザ部分)、2つの開始の間に約15秒の不足があります:

http://prntscr.com/jevgeg vs http://prntscr.com/jevgix 間に何もありません。

19
Lars Holdgaard

解決されていないのに回答を投稿していますが、根本的な問題を見つけたと99%確信しています。

何が起こるかというと、リリースすると、すべてのビューを構築する必要があります。ビューの作成には最大15秒かかります。これは、NewRelicが最新のアップデートでも示していることです。

これにより、2つの一時的な解決策と1つの大きな質問がもたらされます:ビューの構築が非常に遅いのはなぜですか?

一時的な解決策は簡単です。リリース時にビューをコンパイルするか、リリース直後に最も重要なページにアクセスしてください。私は1日に複数回リリースするので、これは明らかに迷惑です。

非常に遅い理由は、私が非常に大きなBootstrapテーマを使用しているためです。バンドルの処理方法はあまり効率的ではなく、問題が発生する可能性があります。

私が苦痛だと思った理由は、サイトが約10分後に遅くなったためです。これは、新しいコードを頻繁にリリースし、ページの大部分にアクセスしなかったためです。これを行った後、それは速いです。

あなたの助けとサポートに感謝します-少なくとも今私はそれに対処することができます。

2
Lars Holdgaard

考えられる答えがいくつかあります。

エンティティフレームワークコードファースト/データベース初期化:移行と場合によってはシードデータを使用してコードファーストセットアップを使用している場合、これらのそれぞれが「ウォームアップ」の問題を引き起こす可能性があります。

特に、アプリの起動時にデータベースを初期化していない場合、データベースに最初にアクセスしたのは、データベースが初期化されたときです。

Entity framwork version: Entity Framework自体も5と6.xで多くのパフォーマンスが向上しました。これらのいくつかは、コールドとウォームの両方の起動速度にも関係しています。

ビューはプリコンパイルされていません:(展開後のように)ページの読み込みが遅い場合は、新しいページ(ビュー)が最初にヒットするたびに、その後の読み込みは問題ありません。これは、ページがコンパイルされていないことが原因である可能性があります。その場合は、それについて詳しく説明できます。

リサイクルアプリケーションがリサイクルされるときにこれらの問題が発生しているようですが、自動初期化されていません(そのため、コールドヒットが発生します)これらの問題で私が見た中で最悪のパフォーマンスの問題は通常ですエンティティフレームワークとプリコンパイル関連。しかし、どちらも簡単に修正できます。ただし、アプリが「常に実行」され、リサイクル後に自己初期化されるようにすることで、このコールドヒットをユーザーが受けないようにすることもできます。

PDATE:ビューに関連していたので、非常に便利なソリューションを提供できます。 RazorGenerator.MvcNugetパッケージをインストールしています。そして、このエンジンを最初のエンジンとして追加すると、コンパイルされたビューを確実に使用できるようになります。

App_Startで、次のような内容のRazorGeneratorMvcStart.csというファイルを作成できます。

using RazorGenerator.Mvc;

[Assembly: WebActivatorEx.PostApplicationStartMethod(typeof(MyNamespace.RazorGeneratorMvcStart), "Start")]

namespace MyNamespace {
    public static class RazorGeneratorMvcStart {
        public static void Start() {
            ViewEngines.Engines.Insert(0, new PrecompiledMvcEngine(typeof(RazorGeneratorMvcStart).Assembly));

            VirtualPathFactoryManager.RegisterVirtualPathFactory(engine);
        }
    }
}

かみそりエンジンは、ライブビューを置き換えるのが好きな人のためにUsePhysicalViewsIfNewerのパラメーターを取ることさえできます。その場合、コンパイルされた.dllよりも新しい日付のビューがフォルダーに配置されていない限り、プリコンパイルされたバージョンが使用されます。

このアプローチは、ビューのパフォーマンスの問題を解決するはずです。

3
Jim Wolff

検索して修正するオプションがさらに2つあります。

1。ユーザー New Relic トレースします。

チェック thisAzureでの使用に関するhanselmanからの投稿。

2。Asp.NetMVCのベストプラクティスに従う

ベストプラクティスについては、 this 投稿を確認してください。

また、データの読み取りには、ADO.NETの代わりにストアドプロシージャでEntity Frameworkを使用できます。これは、現時点ではEFにパフォーマンスの問題がある可能性があるためです。

2
stom

いくつかのアイデア:

  1. Webアプリブレードで、[診断して問題を解決する]メニューに移動します。次に、パフォーマンスカウンターをクリックします。タイムラインとパフォーマンスの低下に注意しながら、利用可能なすべてのパフォーマンスカウンターを正直に調べます。スレッド数を調べたところ、接続が暴走したためにSignalRがサーバーを窒息させていることがわかりました。

  2. Application Insightsのサーバーエラーログインはクリーンですか?

  3. [問題の診断と解決]画面で、失敗した要求のトレースログに疑わしいものがありますか?

2
Rob Reagan
  1. 展開とローカルから何かを分離します。アプリケーションがローカル環境で完全に実行されている場合、Azureに移行すると別のことが起こります。何かを解決するには時間がかかります。
  2. 静的リソース(スクリプト、スタイルなど)は、最初のリクエストでブラウザによって自動的にキャッシュされるため、後続のリクエストでは問題が発生しないはずです。
  3. 「Render」メソッドが問題を引き起こしていることがわかっているので、複雑なネスト計算とブラウザのDOM操作が行われているように見えます。ただし、ローカルでこれが問題にならない場合は、外部リソースの呼び出しをレンダリングし、それらがブロック呼び出しを取得しているかどうかを確認します(ajaxまたはサーバー側の非同期呼び出しを多用する必要がある場合がありますが、すでに配置されていると思います)。
  4. 可能なリファクタリングが必要になる場合があります(スタックを小さくし、スレッド化/非ブロッキングIOを使用できるようにするため)が、それを提案するコードを確認する必要があります。

ページ読み込みイベントとそれによって行われた後続の呼び出しを共有します。また、DOM処理とともにビューがどのようにレンダリングされるか。

2
NitinSingh

バンドル設定でLessまたはSassをコンパイルしていますか?
はいの場合、どのJavaScriptEngineSwitcherを使用していますか?
同様の問題があったことを覚えています。バンドルは最初のアクセスでコンパイルされ、非常に長い時間がかかりました。
解決策はV8エンジンに切り替えることでした。

1
Attila Szasz