web-dev-qa-db-ja.com

リロードせずに.NET Webサイトを更新する

以前はPHPASP classicでWebサイトを開発していましたが、何か変更が必要な場合もありました。単一/複数のファイルを変更するだけで、誰も気付かないでしょう。おそらく、アップロード中に誰かが変更されたファイルを要求するかもしれませんが、それは0.5秒のマージンのようなものです。ほとんどの小規模なサイトでは問題ありません。

しかし、最新のサイトはC#MVCで構築されており、コードに変更を加えた場合、Webサイトを再構築し、変更されたDLLファイルをアップロードする必要があります。ただし、DLLファイルを変更すると、Webサイトが再起動され、アクティブなsessionsがすべてリセットされます。また、すべてをリロードする必要があり、大規模なサイトではすべてをロードするのに数分かかる場合があります。サイトを閲覧していた人は誰でも気づき、再度ログインする必要があります。

主要なサイトの更新はそれほど一般的ではないため、それは問題ではありません。ただし、プロモーションの定期的な「小さな」更新があります。 「このフォームに記入して3か月間無料のメンバーシップを取得する」または「...の画像をアップロードした最初の10人が価格を受け取る」などです。あなたはドリフトを得ると思います。一部のプロモーションは類似しており、設定に基づいて適切な情報を表示するモジュールで処理できますが、多くの場合、カスタムコードが必要です。

私は、各プロモーションがインターフェースに基づいた独自のDLLファイルであり、Type.GetTypeActivator.CreateInstance、およびDLLを使用してInvokeMemberを動的にロードするシステムを考えていました。それはうまくいくかもしれませんが、それが正しい方法かどうか疑問に思っています。

だから私の質問:サイト全体をリロードしてセッションを破棄することなく(アプリケーションプールのリサイクルなど)、.NETサイトをオンザフライで更新するにはどうすればよいですか。

13
Hugo Delsing

「アプリケーションの初期化」を調べる IIS 7.5、Windows 2008 R2 (セットアップが難しい) IIS 8、Windows 2012

アプリの初期化により、すべてのアプリケーション(サイトではなくアプリケーションプール)を再起動して、古いアプリケーションを実行し、新しいアプリケーションの起動をウォームアップしながら以前のアプリケーションを実行できます。新しいアプリケーションがスピンアップすると(設定可能なURLによって決定されます)、新しいアプリケーションの使用が開始され、以前のアプリケーションがシャットダウンされます。アプリケーションの初期化をメソッドと組み合わせて使用​​し、アプリケーションプールの再起動後もセッションが維持されるようにすると、サイトをシームレスに再起動できます。 (Zhaphはマシンキーについて十分な注意を払っています。)

アプリの初期化設定に関する上記のリンクに加えて、サイトの再起動をトリガーするものを確認する必要があります-サイトの再起動ではApplicationInitiliazationサイトの再起動はシームレスではありません。

IISを構成して、DLL更新がすぐにサイトの再起動やweb.configの変更を引き起こさないように構成できます(関連するhttpRuntimeおよび外部構成ファイルのChangeNotification値が高い)あなたのサイトへ)。

最終的な結果は、サイトを再起動せずにDLL /コードを更新し、appを強制的に再起動して、AppInitializationバックグラウンドを使用してコードをシームレスに変更することです。

これらのことをコンサートで行うと、シームレスな再起動に非常にうまく機能します。

11
jeffreypriebe

求めていることを処理する方法はいくつかあり、質問にはいくつかの異なる側面があります。

プロモーションの小さな更新を処理する

ここで本当に必要なのは、コンテンツをオンザフライで編集できるコンテンツ管理システムまたは類似のものです(Wordpress/Drupalまたは.NETの視点N2 CMS、Umbraco、Orchardなどから)そのルートを下っていない場合に試すことができるものがいくつかあります。

ASP.NETは特定の種類のファイル(web.config(s)、/bin/および/app_code/フォルダーの内容)に触れた場合にのみ実際にリロードされるため、「その他のファイル」に対して構成可能な制限があります。変更」(基本的に、サイト内の非常に多くのファイルを変更すると、アプリケーションプールが再起動します- NumRecompilesBeforeAppRestart )いくつかの静的なフォルダーを確認することを確認できます(つまり、.html)必要に応じてプルして表示するファイル、または.ascxユーザーコントロールへの文字列パスを取得して動的にロードするLoadControlメソッドを使用するファイル-表示するものがどの質問に適しているかを判断する方法StackOverflow-ただし、命名規則ベースのソリューションをお勧めします。

Managed Extensibility Framework (MEF-バージョン4以降、.NETフレームワークの一部である)のようなものを使用して調べることもできます。これにより、プラグインベースのアーキテクチャを記述し、フォルダーを指定できます。 /bin/ディレクトリの外部で新しい.DLLを監視します-アプリの再起動の問題を回避できるかどうか確認するためにこれを試したことはありませんが、一般的な機能を追加するためにWeb環境でこれを使用しましたサイト。

それが魅力的でない場合、私が考えることができる他の唯一のオプションは、従来のASPで行ったように、コントロールを「コードインフロント」として追加することです。つまり、<script runat="server">コントロールを実行するロジックを含むコンパイル済みの「コードビハインド」クラスの代わりにブロック-これにより、コントロールが最初にパフォーマンスを失うことを犠牲にして、DLL変更の必要性がなくなります。オンザフライでコンパイルされます-少しの変更をたくさん行う場合は、これをNumRecompilesBeforeAppRestartとバランスさせる必要があります。

アプリの再起動後もセッションを維持するにはどうすればよいですか?

これはおそらく解決が容易な問題であり、3つの重要な手順が含まれます。

  1. MachineKeyを構成します(IIS7、ただし8を保持します)AutoGenerateではなく定数値にする-これは、AppPoolがリサイクルするときに同じキーを使用するため、セッションを復号化できることを意味しますリサイクル前のクッキー、ビューステートなど。
  2. 状態サーバーのセットアップ または セッション状態を保持するデータベースの構成 のいずれかです。
  3. Web.configのSessionState要素で、InProcを使用してからStateServerまたはSQLServerに切り替えます。

この方法では、アプリの再起動後も存続する永続的なセッションがあります。ただし、これらは「無料」ではありません。セッションに保存するものはすべて直列化可能でなければならず、各ページの読み込みでセッションデータを取得し、潜在的に解放するために追加のネットワークトリップが必要になるため、わずかなパフォーマンスヒットが発生します。

ただし、展開後にアプリケーションが再起動するのに「数分」かかる場合は、負荷分散環境への移行、または少なくともホットスワップ可能なステージング/ライブセットアップを検討することをお勧めします。 (Azure/AWSなどによって提供されるものなど)-この方法では、サーバーを更新中にオフラインにするか、新しいコードで準備してからスワップすることができます-共有に対処する手順を実行した場合セッション(上記を参照)は、ユーザーに影響を与えることなく正常に機能します。

5