障害は分散システムでは避けられません。 ハードウェアの障害が発生することがあります。 ネットワークに一時的な障害が起きることがあります。 サービス全体、データセンター、または Azure リージョン全体で中断が発生することはめったにありませんが、ワークロード アーキテクチャではそれらの停止を考慮する必要があります。 ワークロード設計の早い段階で回復性と回復性に対処します。
障害が発生したときに自己復旧するアプリケーションを設計します。 次の方法を使用します。
- エラーを検出します。
- 障害に適切に対応する。
- エラーをログに記録して監視し、運用上の分析情報を提供します。
障害が発生したときに自己修復するようにアプリケーションを設計する
障害への対応をワークロードの可用性要件に合わせます。 たとえば、高可用性が必要な場合は、リージョン内の複数の可用性ゾーンにデプロイできます。 Azure リージョンで中断が発生したときに停止を回避するために、セカンダリ リージョンに自動的にフェールオーバーできます。 この方法では、単一リージョンのデプロイと比較してコストが増加し、パフォーマンスが低下する可能性があります。
地域的な停止などのまれな大規模なイベントだけに焦点を当てないでください。 ネットワーク接続の損失やデータベース接続の障害など、ローカルの有効期間が短い障害に等しく、またはそれ以上の焦点を当てます。
自己復旧型ワークロード設計は、 Azure Well-Architected Framework の信頼性の柱の基本であり、故障に耐え、完全に機能する状態に回復できる回復性のあるシステムの構築に重点を置いています。 サービス レベル目標 (SLO) など、ワークロードの可用性ターゲットをサポートするための自己復旧戦略を構築します。
Recommendations
非同期的に通信する分離コンポーネントを使用します。 時間と空間の観点から分離するコンポーネントを設計します。 時間の切り離しは、コンポーネントが通信のために同時に存在する必要がないようにすることを意味します。 スペース内で切り離すということは、送信側と受信側が同じプロセスで実行する必要がないことを意味します。 分離されたコンポーネントでは、イベントを使用して相互に通信する必要があります。これにより、連鎖障害の可能性を最小限に抑えることができます。
失敗した操作を再試行します。 一時的な障害は、ネットワーク接続の一時的な損失、データベース接続の切断、またはサービスがビジー状態の場合のタイムアウトが原因で発生する可能性があります。 アプリケーションに再試行ロジックを構築して、一時的な障害を処理します。 多くの Azure サービスでは、クライアント SDK が自動再試行を実装します。 詳細については、「一時的な障害の処理」および「再試行パターン」を参照してください。
正常性エンドポイントの監視を実装します。 各サービスは、現在の状態とその依存関係の状態を示す正常性エンドポイントを公開する必要があります。 外部監視システム、ロード バランサー、オーケストレーターは、これらの正常性エンドポイントを使用して、サービスが正常かどうかを判断し、それに応じてトラフィックをルーティングします。 詳細については、「 正常性エンドポイントの監視パターン」を参照してください。
障害が発生したリモート サービスを保護します。 一時的な障害が発生した後に再試行することをお勧めしますが、永続的な障害により、障害が発生したサービスがオーバーロードされ、連鎖的な障害が発生する可能性があります。 サーキット ブレーカー パターンを使用すると、操作が失敗する可能性がある場合にリモート呼び出しを行わずに高速に失敗します。
重要なリソースを分離する。 スレッドやソケットなどのリソースがすぐに解放されないと、1 つのサブシステムの障害が連鎖し、リソースが枯渇する可能性があります。 1 つのパーティションの障害がシステム全体に影響を与えないように、 Bulkhead パターン を使用して、システムを分離されたグループにパーティション分割します。
負荷平準化を実行します。 アプリケーションでは、バックエンドのサービスを圧倒するトラフィックが急激に急増する可能性があります。 Queue-Based 負荷平準化パターンを使用して、作業項目をキューに入れ、非同期的に実行します。 キューは、負荷のピークを滑らかにするバッファーとして機能します。
フェールオーバーします。 インスタンスに到達できない場合は、別のインスタンスにフェールオーバーします。 Web サーバーなどのステートレス コンポーネントの場合は、ロード バランサーまたはトラフィック マネージャーの背後に複数のインスタンスを配置します。 データベースなどのステートフル コンポーネントの場合は、レプリカを使用し、フェールオーバー メカニズムを実装します。 データ ストアとそのレプリケート方法によっては、アプリケーションで最終的な整合性を処理する必要がある場合があります。
失敗したトランザクションを補正します。 一般に、分散トランザクションはサービスとリソース間の調整を必要とするため、避けてください。 代わりに、より小さな個別のトランザクションで 1 つの操作を構成します。 途中で操作が失敗した場合は、 補正トランザクション パターンを 使用して、完了した手順を元に戻します。
実行時間の長いトランザクションにチェックポイントを追加します。 チェックポイントは、実行時間の長い操作が失敗した場合に回復性を提供します。 たとえば、別の仮想マシンが操作を再開すると、最後のチェックポイントから再開できます。 タスクに関する状態情報を一定の間隔で記録するメカニズムを実装することを検討してください。 タスクを実行するプロセスの任意のインスタンスがアクセスできる永続的ストレージにこの状態を保存します。 プロセスがシャットダウンすると、別のインスタンスが最後のチェックポイントから作業を再開できます。 NServiceBus や MassTransit などのライブラリは、この機能を提供します。 これらは透過的に状態を保持し、間隔は Azure Service Bus のキューからのメッセージ処理と一致します。
正常に低下し、障害発生時に応答性を維持します。 問題を回避できない場合もありますが、引き続き役に立つ機能を減らすことができます。 たとえば、アプリケーションがブック カバーのサムネイル画像を取得できない場合は、プレースホルダー画像が表示されることがあります。 注文処理と比較して、eコマース サイトでの製品の推奨事項など、サブシステム全体が重要ではない可能性があります。
クライアントを調整します。 場合によっては、一部のユーザーが過剰な負荷を発生させ、他のユーザーに対するアプリケーションの可用性を低下させる可能性があります。 この状況では、設定された期間、クライアントを調整します。 詳細については、「 調整パターン」を参照してください。
無効なアクターをブロックします。 調整は悪意のある意図を意味するものではありません。 これは、クライアントがサービス クォータを超えたことを意味します。 しかしクライアントが一貫してクォータを超えるまたは不適切な動作をする場合は、それをブロックすることもあります。 ユーザーがブロック解除を要求するための帯域外プロセスを定義します。
リーダーの選択を使用します。 タスクを調整する必要がある場合は、 リーダー選択パターン を使用してコーディネーターを選択します。 この方法により、コーディネーターが単一障害点ではないことが保証されます。 コーディネーターが失敗した場合、システムは新しいコーディネーターを選択します。 カスタム リーダー選択アルゴリズムを実装するのではなく、 Apache ZooKeeper などの事前構築済みのソリューションを検討してください。
フォールト インジェクションを使用してテストします。 多くの場合、成功パスは徹底的なテストを受けますが、失敗パスは受け取りません。 システムは、障害パスがトリガーされる前に、長時間運用環境で実行できます。 障害の挿入を使用して、障害をトリガーまたはシミュレートしてシステムの回復性をテストします。
カオス エンジニアリングを実装する。 カオス エンジニアリングは、運用インスタンスに障害または異常な状態をランダムに導入することで、障害挿入の概念を拡張します。 Azure Chaos Studio などのツールは、自己復旧戦略の弱点を特定する制御されたカオス実験を実行するのに役立ちます。
可用性ゾーンを使用します。 多くの Azure リージョンでは 可用性ゾーンが提供されています。可用性ゾーンは、リージョン内のデータセンターの分離されたセットです。 一部の Azure サービスは 、特定のゾーンに確実に配置され、同じワークロード内のコンポーネント間の通信の待機時間を短縮するのに役立つ、いくつかの Azure サービスをゾーン単位でデプロイできます。 または、 ゾーン冗長を使用して一部のサービスをデプロイすることもできます。つまり、Azure は高可用性のために複数のゾーンにリソースを自動的にレプリケートします。 ソリューションに最適なトレードオフのセットを提供するアプローチを検討します。 詳細については、「 可用性ゾーンとリージョンの推奨事項」を参照してください。 可用性ゾーンをサポートする一部のサービスでは、インスタンスの最小数を 3 に設定するなど、これらのゾーン間で特にスケールアウトするようにサービスを構成する必要があります。
必要以上に追加しないでください。 自己復旧戦略は、コストの制約、パフォーマンス目標、許容されるダウンタイム レベルに合わせる必要があります。 このレベルの自動復旧を必要としないワークロードの一部で自己復旧機能を実装することは避けてください。