昨日、チームと一緒に、シングル ページ アプリケーションをサポートするためにゼロ ダウンタイム デプロイを使用する可能性について話し合っていました。
それについて話し合っているうちに、1 つのエッジ ケースを特定しました。ユーザーがブラウザにページをロードすると、ページをリロードするまでメモリから削除できません。つまり、ユーザーがページをロードして Web サイトで作業を開始した場合 (たとえば、私が今行っているように長い記事を入力し始めた場合)、ページをリロードするまで、更新されたバージョンを受け取ることができません。
ユーザーのブラウザに古いバージョンのアプリケーションが表示されるという事実は無視できますが、以下に示す 2 つの点があります。
- スパを提供するために使用される HTTP Api に重大な変更を導入した場合、ユーザーは記事を保存できなくなったり (データ損失!)、他のバックエンド関連のアクションを実行したときに他のエラーを受け取ったりする可能性があります。
- ユーザーが SPA をリロードせずに新しいページに移動すると、次のページのテンプレートまたは外部の古いコンテナーと互換性のないコントロールのテンプレートを受け取ることができます。マークアップやアプリケーション ロジックの破損につながる可能性があります。
- ユーザーが記事を入力している途中である可能性があるため、ユーザーに再ログインを強制することはできません。これは単に悪い UX です。
これらすべての点を考慮に入れると、次の解決策を提案できます。
- ユーザー 1 は、SPA の v1 をブラウザーにロードします。
- 認証トークンとともに、バージョン情報がブラウザーに送信されます (たとえば、JWT を使用)。
- アプリケーションの v2 バージョンをデプロイしたいと考えています。v2 バージョンをスピンアップしますが、v1 を無効にしません。
- ユーザー 2 は、SPA の v2 を自分のブラウザーに読み込みます
- ユーザー 1 は、SPA の次のページに移動します。ロード バランサーはトークンのバージョン情報をチェックし、ユーザー 1 のトラフィックを v1 サーバーにルーティングします。
- ユーザー 2 は、同じ方法で v2 にルーティングされます。
- ユーザー 1 がアプリをログアウトし、ブラウザーを閉じます。
- ユーザー 1 は再度ログインします。今回は v2 を受け取ります。
- v1 アプリケーションが長時間トラフィックを受信しないと、破棄されます。
ただし、このアプローチでは、2 つ以上の複数のバージョンを有効にすることができます (たとえば、ユーザーが 1 日か 2 日オンラインでいる場合)。これは、最後のユーザーがログアウトするまで、データベースを新しいスキーマに移行できないことを意味します (Facebook などのサイトでどのように機能するかをイメージしてください)。複数のバージョンを使用することは問題ではありませんが、Docker や Rancher などのツールを使用すると簡単に行うことができます。
また、ステップ 7 では、ユーザーはページをリロードするか、ブラウザーを閉じる必要があります。そうしないと、ユーザーはまだ v1 で作業しているため、次のバージョンに強制することはできません。
私が持っている質問は、シングル ページ アプリケーションのゼロ ダウンタイム/Blue-Green デプロイを行うためにどのようなアプローチを使用するかということです。
特に既存の「ブルー」クライアント アプリケーションに関して、トラフィックを「グリーン」バージョンに切り替えるときに、アプリケーションの「ブルー」バージョンの有効期間をどのように管理しますか。
これらの問題を解決しましたか、他の解決策を知っていますか?