Webサイトの新しいバージョンを展開するには、次の手順を実行します。
このプロセスはすべてスクリプト化されており、非常に迅速に行われますが、古いファイルが削除され、新しいファイルが展開されると、10〜20秒のダウンタイムが発生する可能性があります。
0秒のダウンタイム方法に関する提案はありますか?
2台のサーバーとロードバランサーが必要です。手順は次のとおりです。
この場合でも、「スティッキーセッション」を使用している場合は、アプリケーションの再起動とセッションの損失が発生します。データベースセッションまたは状態サーバーがある場合は、すべて正常です。
Microsoft Web Deployment Tool はこれをある程度サポートしています:
Windows Transactional File System(TxF)サポートを有効にします。 TxFサポートが有効な場合、ファイル操作はアトミックです。つまり、成功するか、完全に失敗します。これにより、データの整合性が確保され、データまたはファイルが「途中」または破損した状態で存在することが防止されます。 MS Deployでは、TxFはデフォルトで無効になっています。
トランザクションは同期全体のようです。また、TxFはWindows Server 2008の機能であるため、このトランザクション機能は以前のバージョンでは機能しません。
フォルダーをバージョンとして使用し、IISメタベース:0ダウンタイムのスクリプトを変更することは可能だと思います。
この方法には次の利点があります。
IIS異なるポート上の2つのローカルIISサイト間のソフトウェアロードバランサーとしてApplication Request Routingを利用することにより、単一サーバーでゼロダウンタイムの展開を実現できます。 blue greenデプロイメント戦略として知られ、2つのサイトのうち1つだけがロードバランサーで常に利用可能です。 「ダウン」し、ウォームアップし、ロードバランサーに持ち込んで(通常はApplication Request Routingヘルスチェックに合格して)、稼働していた元のサイトを「プール」から取り出します(ヘルスチェックを失敗させます) )。
私は最近これを経験しましたが、私が思いついた解決策は、IISに2つのサイトを設定し、それらを切り替えることでした。
私の構成では、AおよびBサイトごとに次のようなWebディレクトリがありました。c:\ Intranet\Live A\Interface c:\ Intranet\Live B\Interface
IISには、それぞれ独自のアプリケーションプールを持つ2つの同一のサイト(同じポート、認証など)があります。一方のサイトが実行され(A)、もう一方のサイトが停止されます(B)。ライブヘッダーには、ライブホストヘッダーもあります。
ライブにデプロイする場合は、STOPPEDサイトの場所に公開するだけです。ポートを使用してBサイトにアクセスできるため、最初のユーザーがアプリケーションを起動させないようにサイトを事前に暖めることができます。次に、バッチファイルを使用して、ライブホストヘッダーをBにコピーし、Aを停止してBを開始します。
Microsoft.Web.AdministrationのServerManagerクラスを使用して、独自の展開エージェントを開発できます。
秘Theは、VirtualDirectoryのPhysicalPathを変更することです。これにより、古いWebアプリと新しいWebアプリがオンラインでアトミックに切り替わります。
これにより、古いAppDomainと新しいAppDomainが並行して実行される可能性があることに注意してください!
問題は、データベースなどへの変更を同期する方法です。
古いまたは新しいPhysicalPathsでAppDomainsの存在をポーリングすることにより、古いAppDomainが終了したとき、および新しいAppDomainが起動したかどうかを検出できます。
AppDomainを強制的に起動するには、HTTPリクエストを行う必要があります(IIS 7.5は自動起動機能をサポートしています)
次に、新しいAppDomainのリクエストをブロックする方法が必要です。名前付きミューテックスを使用します。これは、展開エージェントによって作成および所有され、新しいWebアプリのApplication_Startによって待機され、データベースの更新が行われると展開エージェントによってリリースされます。
(Webアプリでmutexの待機動作を有効にするためにマーカーファイルを使用します)新しいWebアプリが実行されたら、マーカーファイルを削除します。
OKだから、私が2008年に書いた答えを誰もが否定しているので...
2014年の現在の方法を説明します。現在ASP.NET MVCを使用しているため、Webサイトは使用していません。
ロードバランサーと2台のサーバーは必要ありません。維持するすべてのWebサイトに3台のサーバーがある場合は問題ありませんが、ほとんどのWebサイトでは完全に過剰です。
また、マイクロソフトの最新のウィザードに依存していません-遅すぎ、隠された魔法が多すぎ、名前を変更しがちです。
方法は次のとおりです。
生成されたDLLを「bin-pub」フォルダーにコピーするビルド後の手順があります。
Beyond Compare(優れている**)を使用して、変更されたファイル(広くサポートされているFTP経由)を検証し、運用サーバーまで同期します。
Webサイトには、「bin-pub」内のすべてを「bin」にコピーするボタンを含む安全なURLがあります(最初にバックアップを取り、クイックロールバックを有効にします)。この時点で、アプリは自動的に再起動します。次に、ORMは、追加する必要があるテーブルまたは列があるかどうかをチェックし、それらを作成します。
それはわずか数ミリ秒のダウンタイムです。アプリの再起動には1〜2秒かかりますが、再起動中はリクエストがバッファリングされるため、ダウンタイムは事実上ゼロになります。
展開プロセス全体には、変更されるファイルの数とレビューする変更の数に応じて、5秒から30分かかります。
この方法では、Webサイト全体を別のディレクトリにコピーする必要はなく、binフォルダーだけにコピーする必要があります。また、プロセスを完全に制御し、何が変化しているかを正確に把握できます。
**私たちは常に、展開中の変更を素早く確認します-最後の最後のダブルチェックとして、何をテストし、何かが準備できていないかどうかを確認します。 Beyond Compareを使用するのは、FTPを介してファイルを簡単に比較できるためです。私はBCなしではこれを決してしません、あなたはあなたが何を上書きしているのか分かりません。
*下にスクロールして表示してください:展開:マイナーな問題を非常にすばやく修正し、展開しているものを正確に確認できます(もちろん、Beyond Compareを使用している場合-それ以外の場合は忘れてください)。
考えられる唯一のゼロダウンタイムメソッドは、少なくとも2台のサーバーでホストすることです。
これは私がそれを行う方法です:
絶対最小システム要件:
1台のサーバー
ワークフロー:
トランザクションmyupdateを開始します
try
Web-Service: Tell all applications on all web-servers to go into primary read-only mode
Application switch to primary read-only mode, and responds
Web sockets begin notifying all clients
Wait for all applications to respond
wait (custom short interval)
Web-Service: Tell all applications on all web-servers to go into secondary read-only mode
Application switch to secondary read-only mode (data-entry Fuse)
Updatedb - secondary read-only mode (switches database to read-only)
Web-Service: Create backup of database
Web-Service: Restore backup to new database
Web-Service: Update new database with new schema
Deploy new application to apt-repository
(for windows, you will have to write your own custom deployment web-service)
ssh into every machine in array_of_new_webapps
run apt-get update
then either
apt-get dist-upgrade
OR
apt-get install <packagename>
OR
apt-get install --only-upgrade <packagename>
depending on what you need
-- This deploys the new application to all new chroots (or servers/VMs)
Test: Test new application under test.domain.xxx
-- everything that fails should throw an exception here
commit myupdate;
Web-Service: Tell all applications to send web-socket request to reload the pages to all clients at time x (+/- random number)
@client: notify of reload and that this causes loss of unsafed data, with option to abort
@ time x: Switch load balancer from array_of_old_webapps to array_of_new_webapps
Decomission/Recycle array_of_old_webapps, etc.
catch
rollback myupdate
switch to read-write mode
Web-Service: Tell all applications to send web-socket request to unblock read-only mode
end try
Sklivvzの答えを拡張するには、何らかの種類のロードバランサー(または同じサーバー上の単なるスタンバイコピー)に依存していました。
データベースのスナップショット/コピーを作成することにより、少しのスモークテストを導入することは可能ですが、それが常に実行可能であるとは限りません。
可能であれば、異なるテナントURL:s(customerX.myapp.net)または異なるユーザーなどの「ルーティングの違い」を使用して、知らないモルモットのグループに最初に展開します。何も失敗しない場合は、全員にリリースします。
データベースの移行が関係しているため、多くの場合、以前のバージョンへのロールバックは不可能です。
これらのシナリオでは、イベントキューや再生メカニズムを使用するなど、アプリケーションをより適切に再生する方法がありますが、使用中の何かに変更を展開することについて話しているため、実際に確実な方法はありません。
次のように、単一のサーバーについて、ジョージの答えを少し改良します。
手順4では、IISワーカープロセスがリサイクルされます。
InProcセッションを使用していない場合、これはゼロダウンタイムのみです。可能であれば、代わりにSQLモードを使用します(さらに良いのは、セッション状態を完全に回避することです)。
もちろん、複数のサーバーやデータベースの変更がある場合は、もう少し複雑になります。