著者注–このブログ投稿はシリーズの 6 番目です。
これら 6 つのブログと、マイクロサービス アプリケーションの Web フロントエンドに関するブログ <.htmla> が、無料の電子書籍にまとめられています。
マイクロサービスに関するその他の NGINX リソースもご覧ください。
マイクロサービス アプリケーション設計により、アプリケーションの機能に大きな変化がもたらされました。 マイクロサービス アーキテクチャでは、「アプリケーション」は、タスクを実行し機能を提供するために相互に依存するサービスの集合になります。 複雑なアプリケーションでは、サービス グラフが非常に深くなり、さまざまなサービス間に複数の相互依存関係が存在する場合があります。
たとえば、ユーザー サービスは、そのサービスによって提供されるデータに依存する他の多くのサービスに不可欠な場合があります。 このシナリオでは、ユーザー サービスの障害により、アプリケーション全体に連鎖的な障害が発生する可能性があります。
サーキット ブレーカー パターン(Martin Fowler によって普及した用語) は、連鎖的なサービス障害を回避するためのアプリケーション設計パターンとして、マイクロサービス アーキテクトの間で普及しつつあります。 サーキット ブレーカー パターンの考え方は、アプリケーション サービスとそれらの間で流れるトラフィックを監視して障害を防止し、障害が発生した場合には、その障害がアプリケーションに与える影響を最小限に抑えることです。
マイクロサービスの場合、サーキット ブレーカー パターンは特に価値があり、ボトムアップの回復力を提供します。 正しく実装されていれば、サービスが利用できない場合でもサービスの継続性が提供され、連鎖的な障害を回避するのに役立ちます。 サーキットブレーカー パターンは、アプリケーション設計哲学における重要な要素としてNetflix によって採用されていることで最もよく知られています。
現代のアプリケーション設計の重要な原則は、障害が発生するということです。 クラウドでホストされる仮想マシンからコンテナ、アプリケーション ライブラリ、動的ネットワークに至るまで、現代のアプリケーションが依存する階層化されたケーキは、あらゆるアプリケーション内の可動部分が無数にあることを意味します。 アプリケーションの 1 つ以上の部分が、ある時点で何らかの形で失敗すると想定する必要があります。 障害を予測し、その影響を軽減するメカニズムを組み込むことは、アプリケーションの回復力を高めるのに大いに役立ちます。
サーキットブレーカー パターンの最も重要な目標の 1 つは、そもそも障害を防ぐことです。 メモリ不足などの一部のタイプのエラー状態では、障害が差し迫っていることを認識し、それを防ぐための対策を講じることができます。 これは通常、サービスが正常でないことを通知し、サーキット ブレーカーがリクエストの数を減らすか、リクエストを完全に再ルーティングすることでサービスに回復の機会を与えることによって実現されます。 サービスが回復したら、すぐにサービスに過負荷がかかり、再び不健全になるリスクがないように、サーキット ブレーカーでサービスへのリクエストを徐々に増やすことも賢明です。
NGINX マイクロサービス リファレンス アーキテクチャには、 resizerと呼ばれるサービスがあります。 大きな写真がシステムにアップロードされると、リサイズ機能はそれを解凍し、回転を修正し、縮小し、さらに縮小して、修正された元の画像と 2 つのサイズ変更された画像をオブジェクト ストアに保存します。 これらのプロセスの性質上、リサイザーはアプリケーションの中で最もプロセッサとメモリを集中的に使用する部分になります。
多数の画像を同時にサイズ変更すると、リサイズ機能がメモリ不足になり、場合によっては完全に失敗することがあります。 問題を回避するために、リサイズ サービスのインスタンスと、それらに画像を供給するアップローダーサービスのインスタンスの間にサーキット ブレーカーを配置します。 アップローダーは、リサイザー インスタンスのヘルス状態を定期的に照会します。 このクエリにより、リサイザーが使用可能なメモリの 80% 以上を使用しているかどうかを評価するなどのヘルス チェックが実行され、アップローダーにヘルス ステータスが応答されます。
リサイザー インスタンスが正常でないことを示す場合、アップローダーはリクエストを他のインスタンスにルーティングしますが (図 1 を参照)、そのリサイザー インスタンスが回復したかどうかを継続的に確認します。 リサイザー インスタンスが再び正常であることを示すと、そのインスタンスは負荷分散プールに戻され、アップローダーはゆっくりとトラフィックをインスタンスの最大容量まで増加させます。 この設計により、リサイザーのインスタンスが完全に失敗することがなくなり、作業が開始されたが完了しないことがなくなり、プロセスが失敗するユーザーを過度に待たせることがなくなり、システムが送信された要求ストリームを最も効率的に処理できるようになります。
NGINX レベルでサーキット ブレーカーを実装する利点の 1 つは、マイクロサービス アプリケーション全体でサーキット ブレーカーを管理するための、汎用的で一貫性があり、柔軟性の高いレイヤーが作成されることです。 この普遍性と一貫性により、各言語のサーキットブレーカー ライブラリのニュアンスや矛盾を管理したり、それを考慮して構築したりする必要がなくなります。
サーキットブレーカー機能のほとんどを各サービスのコードから切り離し、代わりに NGINX Plus に実装することで、多くの利点が得られます。
ただし、サーキットブレーカーは NGINX Plus だけでは実装できないことに注意することが重要です。 真のサーキット ブレーカーでは、指定された URI (通常は/health ) でサービスがイントロスペクティブでアクティブなヘルス チェックを提供する必要があります。 ヘルス チェックは、特定のサービスのニーズに適したものでなければなりません。
ヘルス チェックを開発する際には、サービスの障害プロファイルと、データベース接続障害、メモリ不足状態、ディスク容量不足、CPU の過負荷など、障害を引き起こす可能性のある状態の種類を理解する必要があります。 これらの状態はヘルス チェック プロセスで評価され、正常または異常のバイナリ ステータスが提供されます。
ここで説明したように、NGINX レベルでサーキット ブレーカー パターンを実装すると、サービス インスタンスが異常であると通知されたときの状況に対処するのは NGINX Plus の責任になります。 いくつかのオプションがあります。
最初のオプションは、リクエストを他の正常なインスタンスにリダイレクトし、正常でないインスタンスをクエリし続け、回復するかどうかを確認することです。 2 番目のオプションは、サービスが利用できない場合でも安定性を維持しながら、サービスを要求するクライアントにキャッシュされた応答を提供することです。 このソリューションは、コンテンツ サービスなどの読み取り指向のサービスに適しています。
もう 1 つのオプションは、代替データ ソースを提供することです。 たとえば、当社の顧客は、プロファイル データを使用してユーザーにターゲット広告を配信するパーソナライズされた広告サーバーを所有しています。 パーソナライズされた広告サーバーがダウンしている場合、ユーザー リクエストは、すべてのユーザーに適した一般的な広告セットを提供するバックアップ サーバーにリダイレクトされます。 この代替データ ソース アプローチは非常に強力です。
最後に、サービスの障害プロファイルを明確に理解している場合は、サーキットブレーカーにレート制限を追加することで障害を軽減できます。 リクエストは、サービスが処理できる速度でのみサービスに許可されます。 これにより、サーキットブレーカー内にバッファが作成され、トラフィックの急増を吸収できるようになります。
レート制限は、ルータ メッシュ モデルのような集中型負荷分散シナリオで特に強力になります。ルータ メッシュ モデルでは、アプリケーション トラフィックが限られた数のロード バランサを介してルーティングされ、サイト全体のトラフィック使用量全体を適切に把握できます。
上で説明したように、サーキット ブレーカー パターンは、不健全なサービスへのトラフィックを減らしたり、リクエストをそのサービスからルーティングしたりすることで、障害が発生する前にそれを防ぐことができます。 これには、各サービス上の内部ヘルスモニターに接続されたアクティブなヘルスチェックが必要です。 残念ながら、パッシブなヘルスチェックでは障害のみをチェックするため、その時点では予防措置を講じるにはすでに手遅れです。 このため、NGINX オープンソースはサーキットブレーカーパターンを実装できず、パッシブなヘルスチェックのみをサポートしています。
ただし、NGINX Plus には、ヘルスの問題をチェックして対応するための多くのオプションを備えた強力なアクティブ ヘルスチェック システムがあります。 マイクロサービス リファレンス アーキテクチャのいくつかのサービス タイプの実装を見ると、サーキット ブレーカーを実装するためのオプションとユース ケースの良い例がわかります。
まずは、リサイズツールに接続するアップローダー サービスから始めましょう。 アップローダーは画像をオブジェクト ストアに配置し、リサイザーに画像を開いて修正し、サイズを変更するように指示します。 これは、計算負荷とメモリ負荷の高い操作です。リサイザーは、実行中のホストを文字通り強制終了する可能性があるため、アップローダーはリサイザーの状態を監視し、過負荷を回避する必要があります。
最初に行うことは、リサイザーのヘルスチェック専用のロケーション
ブロックを作成することです。 このブロックは内部の
場所であるため、サーバーの標準 URL ( http://example.com/health-check-resizer ) へのリクエストではアクセスできません。 代わりに、ヘルスチェック情報のプレースホルダーとして機能します。 health_check
ディレクティブは、3 秒ごとに/health URI にヘルス チェックを送信し、 conditionsと呼ばれる一致
ブロックで定義されたテストを使用して、サービス インスタンスのヘルスをチェックします。 サービス インスタンスは、1 つのチェックに失敗すると、異常としてマークされます。 proxy_*
ディレクティブは、指定された HTTP ヘッダーを null に設定して、HTTP 1.1 経由の TLS 1.2 を使用して、ヘルス チェックをresizerアップストリーム グループに送信します。
location /health-check-resizer { internal;
health_check uri=/health match=conditions fails=1 interval=3s;
proxy_pass https://resizer;
proxy_ssl_session_reuse on;
proxy_ssl_protocols TLSv1.2;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Accept-Encoding "";
}
次のステップは、条件一致
ブロックを作成して、健全な状態と不健全な状態を表す応答を指定することです。 最初のチェックはレスポンスステータスコードです。200
を通して399
テストは次の評価ステートメントに進みます。 2 番目のチェックは、 Content-Type
がapplication/json
であるかどうかです。 最後に、3 番目のチェックは、デッドロック
、ディスク
、およびメモリ
メトリックの値に対する正規表現の一致です。 すべてが正常であれば、サービスは正常であると判断されます。
一致条件 { ステータス 200-399;
ヘッダー Content-Type ~ "application/json";
本文 ~ '{
"deadlocks":{"healthy":true},
"Disk":{"healthy":true},
"Memory":{"healthy":true}
}';
}
NGINX Plus のサーキットブレーカー/ヘルスチェック システムには、スロースタート機能もあります。アップストリーム
ブロックのリサイザー サービスのサーバー
ディレクティブのslow_start
パラメーターは、リサイザー インスタンスが最初に不健全な状態から戻ったときに、NGINX Plus にトラフィックのフローを調整するように指示します。 正常なサービスに同じ数のリクエストを送信してサービスをただ集中的に処理するのではなく、回復中のサービスへのトラフィックは、 slow_start
パラメータで指定された期間 (この場合は 30 秒) にわたってゆっくりと通常の速度まで増加します。 スロースタートにより、サービスが完全に機能しなくなる可能性が高まり、サービスが完全に機能しなくなる場合の影響が軽減されます。
アップストリーム リサイザー { サーバー リサイザー slow_start=30s;
ゾーン バックエンド 64k;
least_time last_byte;
keepalive 300;
}
リクエスト制限は、サービスへのリクエストのフローを管理および調整します。 アプリケーションの障害プロファイルを十分に理解し、特定の時点で処理できるリクエストの数を把握している場合は、リクエスト制限を実装すると、プロセスに大きなメリットをもたらす可能性があります。 ただし、この機能は、NGINX Plus がサービスに渡される接続の合計数を完全に認識している場合にのみ機能します。 このため、ファブリック モデルのようにサービス自体を含むコンテナ内で実行されている NGINX Plus インスタンス、またはクラスター内のすべてのトラフィックを管理する集中型ロード バランサーに、リクエスト制限サーキット ブレーカーを実装するのが最も便利です。
次の構成コード スニペットは、コンテナー内のリサイズ サービス インスタンスに適用されるリクエストのレート制限を定義します。 limit_req_zone
ディレクティブは、1 秒あたり 100 リクエストのレート制限を定義します。 $server_addr
変数がキーとして使用され、リサイザー コンテナーへのすべてのリクエストが制限にカウントされることを意味します。 ゾーンの名前はmoderateReqsで、リクエスト数を保持する時間枠は 1 分です。 limit_req
ディレクティブにより、NGINX Plus は最大 150 件のリクエストのバーストをバッファリングできるようになります。 その数を超えると、クライアントは503
limit_req_status
ディレクティブで指定されたエラー コード。サービスが利用できないことを示します。
http { # モデレート配信
limit_req_zone $server_addr zone=moderateReqs:1m rate=100r/s;
# ...
server {
# ...
limit_req zone=moderateReqs burst=150;
limit_req_status 503;
# ...
}
}
NGINX Plus 内でサーキット ブレーカーを実行するもう 1 つの強力な利点は、キャッシュを組み込み、キャッシュされたデータを集中的に管理してシステム全体で使用できることです。 これは、バックエンドから読み取られるデータが頻繁に変更されないコンテンツ サーバーなどの読み取り指向のサービスに特に役立ちます。
proxy_cache_path /app/cache levels=1:2 keys_zone=oauth_cache:10m max_size=10m inactive=15s use_temp_path=off;
upstream user-manager {
server user-manager;
zone backend 64k;
least_time last_byte;
keepalive 300;
}
server {
listen 443 ssl;
location /v1/users {
proxy_pass http://user-manager;
proxy_cache oauth_cache;
proxy_cache_valid 200 30s;
proxy_cache_use_stale error timeout invalid_header 更新中
http_500 http_502 http_503 http_504;
}
}
図 2 に示すように、データをキャッシュすると、多くの顧客データ要求がマイクロサービス インスタンスに到達しなくなり、以前に受信されなかった要求のために容量が解放されます。
ただし、ユーザー マネージャー サービスなど、データが変更できるサービスでは、キャッシュを慎重に管理する必要があります。 そうしないと、ユーザーが自分のプロファイルを変更しても、データがキャッシュされているため、一部のコンテキストでは古いデータが表示されるというシナリオが発生する可能性があります。 適切なタイムアウトと、最終的な一貫性を備えた高可用性の原則を受け入れることで、この難問を解決できます。
NGINXキャッシュの優れた機能の1つは、サービスが完全に利用できなくなってもキャッシュされたデータの提供を継続できることです。上記のスニペットでは、サービスが4つの最も一般的な応答のいずれかで応答している場合、500
‑シリーズのエラー コード。
サーバーがダウンした場合でもクライアントに応答するためのオプションはキャッシュだけではありません。 「サーキット ブレーカー パターンによる柔軟性の提供」で述べたように、当社の顧客の 1 社では、パーソナライズされた広告サーバーがダウンした場合に備えて回復力のあるソリューションを必要としていましたが、キャッシュされた応答は適切なソリューションではありませんでした。 代わりに、パーソナライズされたサーバーがオンラインに戻るまで、汎用広告サーバーが一般的な広告を提供することを望んでいました。 これは、サーバー
ディレクティブのバックアップ
パラメータを使用することで簡単に実現できます。 次のスニペットは、 personal-ad-serverドメインに定義されたすべてのサーバーが利用できない場合に、代わりにgeneric-ad-serverドメインに定義されたサーバーを使用することを指定します。
アップストリーム パーソナル広告サーバー { サーバー パーソナル広告サーバー;
サーバー ジェネリック広告サーバー バックアップ;
ゾーン バックエンド 64k;
最小時間 最終バイト;
キープアライブ 300;
}
そして最後に、NGINX にサービスからの応答コードを評価させ、それらを個別に処理させることも可能です。 次のスニペットでは、サービスが503
エラーが発生した場合、NGINX Plus はリクエストを代替サービスに送信します。 たとえば、リサイザーにこの機能があり、ローカル インスタンスが過負荷になったり機能が停止したりした場合、リクエストはリサイザーの別のインスタンスに送信されます。
場所 / { error_page 503 = @fallback;
}
場所 @fallback {
proxy_pass http://alternative-backend;
}
サーキットブレーカー パターンは、マイクロサービス アプリケーションに回復力と制御を提供する強力なツールです。 NGINX Plus は、環境にサーキットブレーカーを実装するための多くの機能とオプションを提供します。 サーキット ブレーカー パターンを実装する鍵は、保護するサービスの障害プロファイルを理解し、可能な場合は障害を最も効果的に防止し、障害が発生した場合にはその影響を最も効果的に軽減するオプションを選択することです。
NGINX Plus をお試しいただくには、今すぐ30 日間の無料トライアルを開始するか、弊社にお問い合わせの上、使用事例についてご相談ください。
「このブログ投稿には、入手できなくなった製品やサポートされなくなった製品が参照されている場合があります。 利用可能な F5 NGINX 製品およびソリューションに関する最新情報については、 NGINX 製品ファミリーをご覧ください。 NGINX は現在 F5 の一部です。 以前の NGINX.com リンクはすべて、F5.com の同様の NGINX コンテンツにリダイレクトされます。"