グレースフルデグラデーション
Graceful Degradation ・ グレースフルデグラデーション
全部が無理なら一部だけでも動かし続ける設計。完全停止ではなく品質を落として生き残る。
概要
グレースフルデグラデーション(graceful degradation、優雅な劣化)は、システムの一部が壊れたときに全体を止めるのではなく、品質や機能を段階的に落としながら動き続けるための設計です。「動くか、止まるか」の二択ではなく、その間に「劣化しつつ動く」という段階を意図的に用意しておく、と言い換えられます。日本語の「縮退運転」もほぼ同じ概念です。
身近な例はECサイトのレコメンド機能です。「あなたへのおすすめ」を計算するサービスが落ちたとき、商品ページごと500エラーにするのは最悪の選択です。おすすめ欄だけを人気商品ランキングに差し替える、それも無理なら欄ごと非表示にする — こうすれば、サイトの本業である「商品を見て買う」体験は無傷で生き残ります。多数の部品に依存するマイクロサービス構成では、部品のどれかが不調であることはむしろ平常であり、劣化の段階をあらかじめ設計しておくことがシステム全体の可用性を決めます。
なぜ生まれたか
素朴に作られたシステムは、依存関係が「AND条件」になりがちです。ページを組み立てるのに5つのサービスを呼び、そのうち1つでも失敗したら例外がそのまま伝播してページ全体がエラーになる。この作りでは、システム全体の可用性は全部品の可用性の掛け算になり、部品を増やすほど確実に悪化します。可用性99.9%の部品を10個直列に並べれば、全体は99%まで落ちる計算です。分散システムの規模が大きくなるにつれ、「すべてが同時に健全である」ことを前提にした設計は成立しなくなりました。
そこで発想を逆転させ、「部品の失敗は必ず起きる。起きたときに何を諦め、何を守るかを先に決めておく」というアプローチが定着しました。障害を珍しい例外ではなく通常の入力として扱い、失敗時の代替動作(フォールバック)をコードとして書いておく。これにより、致命的でない部品の障害は「気づく人も少ない小さな劣化」に格下げされます。なお、Web制作の文脈にも同名の用語があり、そちらは「最新ブラウザ向けに作り、古い環境では機能を削って表示する」方針を指します。低い環境を基準に積み上げる progressive enhancement(漸進的強化)の対義語で、「段階を設計する」という思想は共通ですが、本記事で扱うのは障害時の劣化設計のほうです。
詳細
フォールバックの階段を設計する
グレースフルデグラデーションの中心作業は、機能ごとに「劣化の階段」を設計することです。第一候補が失敗したら第二候補、それも失敗したら最終手段、と品質の降順に代替を並べます。レコメンドの例なら、パーソナライズ推薦 → 全体の人気ランキング → 静的なデフォルト表示、という三段です。下の段ほど品質は落ちますが、「何も表示できずエラーになる」よりは常に良い、という順序が保たれています。
階段を降りる引き金になるのは、依存先呼び出しの失敗やタイムアウトです。ここで重要なのは「速く諦める」ことです。フォールバックが用意されていても、第一候補を30秒待ってから切り替えたのではユーザー体験は壊れています。短いタイムアウトで見切りをつけ、サーキットブレーカーが開いている間は最初から第一候補を呼ばずに階段の下から始める。回復性パターンの仲間であるリトライ(指数バックオフ)やバルクヘッドが「失敗の検知と封じ込め」を担い、グレースフルデグラデーションが「失敗した後にどう振る舞うか」を担う、という分業です。
劣化の道具箱 — stale応答・機能の切り離し・軽量モード
フォールバックの実装でもっとも頼れる道具はキャッシュです。データソースが落ちていても、少し前に取得した値がキャッシュに残っていれば、「古い(stale)が妥当な応答」を返せます。為替レートや在庫数のように鮮度が命のデータでは慎重さが要りますが、商品説明やランキングのようなデータなら「10分前の値」で困る場面はほとんどありません。平常時は鮮度のために短くしているキャッシュ寿命を、障害時だけ「期限切れでも使ってよい」と緩める stale-while-revalidate 系の戦略は、劣化設計の定番です。
もう一つの道具は、機能単位の切り離しです。フィーチャーフラグをキルスイッチとして仕込んでおけば、障害や過負荷の際に「レコメンド」「画像の高解像度配信」「リアルタイム通知」といった非中核機能を運用判断で即座に落とせます。デプロイなしで負荷の源を止められるため、インシデント対応の初動で効く道具です。さらに進んで、高負荷時にシステム自身が重い処理を自動で間引く設計もあります。過負荷時に一部リクエストを意図的に拒否するロードシェディングや、上流に減速を伝えるバックプレッシャーは、「全員に遅い応答」より「一部を断って残りに正常な応答」を選ぶという意味で、劣化設計の一形態といえます。
落とし穴 — 静かな劣化と、劣化パスの品質
グレースフルデグラデーションには特有の危険があります。それは劣化が静かに起きることです。エラー画面なら誰でも気づきますが、「おすすめ欄が人気ランキングにすり替わっている」状態は、ユーザーからの通報もなく何週間も見過ごされ得ます。フォールバックが発動したら必ずメトリクスとログに残し、発動率の上昇でアラートを出す — 劣化設計はモニタリングとセットで初めて完成します。「フォールバックのおかげで障害に気づかなかった」は成功談ではなく、根本原因の放置です。
もう一つの落とし穴は、フォールバック自体の品質です。劣化パスは平常時に通らないコードなので、いざ発動したら壊れていた、フォールバック先が本命より重くて共倒れした、という事故が起こりがちです。劣化パスもテストに含め、カオスエンジニアリングの手法で依存先の障害を注入して定期的に「階段を実際に降りてみる」ことが、絵に描いた縮退にしないための実務です。何をどこまで守るかの基準は、サービスのSLOから逆算して決めます。「決済は絶対、閲覧は劣化許容、レコメンドは停止許容」のように機能へ優先度を付けておくことが、障害の夜に迷わないための設計図になります。
