カオスエンジニアリング早見表【2025年版】用語・指標・計算式

近年、主要クラウド/ベンダーのガイダンスでは、単なる監視強化だけでなく、設計段階から意図的に故障を注入し回復力を検証する「カオスエンジニアリング」の有効性が強調されています¹。加えて、SLOとエラーバジェットを軸にした運用設計はSREの実践として確立しており、意思決定とリリース・ガードレールの基盤として推奨されています²。本稿は、CTO/エンジニアリーダー向けに、2025年に押さえるべき用語・指標・計算式を早見表として整理し、最小コストで開始できる実装コードと、導入後のベンチマーク・ROI評価までを一気通貫で示します。
課題と前提条件:2025年のカオス実装
現場の課題は次の3点に集約されます。第一に、SLO/エラーバジェットを軸にした実験設計が曖昧で、失敗の影響範囲(ブラスト半径)を制御できていない³。第二に、フロントエンド(FE)とバックエンド(BE)の責務切り分けが曖昧で、ネットワーク揮発性やサードパーティ依存の故障モードが盲点になっている。第三に、実験の観測と学習が継続的デリバリと接続せず、収益や顧客体験と結びつけた意思決定ができていないことです²。
本記事の前提条件と対象環境は以下です。
- 対象: Web/モバイル向けBFF+SPA構成、Kubernetes上で稼働、Node.js 18+、Go 1.21+、Python 3.11+
- 観測: OpenTelemetry/Prometheus/Grafana、フロントはRUM(p95 LCP/INP)
- 開始コスト: 2スプリント(3〜4週間)でパイロット実施可能¹
早見表:用語・指標・計算式
用語集(要点)
用語 | 定義 | 補足 |
---|---|---|
Steady State | 平常時のビジネス/技術の期待値 | 例: p95 API応答<200ms、FE LCP p95<2.5s |
Hypothesis | 故障注入してもSteady Stateが保たれる仮説 | 反証可能性が鍵 |
Blast Radius | 実験が影響する範囲 | カナリア/トラフィック比率で制御³ |
Abort Condition | 実験中止基準 | 例: エラー率>2% or LCP>4s。ルール定義そのものを事前合意しておく⁴ |
Error Budget | SLO未達許容度 | 月間許容ダウンタイムや変更速度の管理に用いる²⁵ |
主要指標と計算式
指標 | 式 | 目的 |
---|---|---|
エラー率 | failed_requests / total_requests | 品質の一次指標 |
可用性(%) | (1 - エラー率) × 100 | SLO評価 |
エラーバジェット(分/月) | (1 - SLO) × 43200 | 30日×24h×60min前提。SLO 99.9% → 43.2分²⁵ |
ブラスト半径(%) | affected_traffic / total_traffic × 100 | 実験安全性³ |
MTTD | 検知時刻 - 発生時刻 | 監視の敏感度⁶ |
MTTR | 復旧時刻 - 検知時刻 | 回復力⁶ |
Retry予算 | max_retry_RPS = error_budget_RPS × k | 過剰リトライ抑制(指数バックオフ+ジッタ前提)⁷ |
RUM p95 LCP | 95パーセンタイルのLCP | FE体感指標 |
実装手順とコード例
実装手順(安全第一の最小セット)
- Steady State定義:API p95<200ms、FE LCP p95<2.5s をSLOに設定。月SLO 99.9% → エラーバジェット43.2分²。
- ブラスト半径1%でカナリア配信(Header/Feature Flagで振り分け)。Abort条件はエラー率>2% or p95>2倍³⁴。
- フェイルファスト設計:タイムアウト、サーキットブレーカー、バックオフ、キャッシュを実装⁷。
- 観測:OpenTelemetryでトレース、PrometheusでSLI収集。RUMでFE p95を送信。カオス実験の前提として計測と可視化を整備¹。
- 段階的実験:レイテンシ注入→ネットワーク切断→依存サービス障害の順で強度を上げる¹。
コード例1:Node.js(Express) フェイルファスト+タイムアウト
上流遅延に対して200msで打ち切り、エラーハンドリングを統一します。
import express from 'express';
const app = express(); app.get(‘/api’, async (req, res) => { const ctl = new AbortController(); const t = setTimeout(() => ctl.abort(), 200); try { const r = await fetch(‘https://httpbin.org/delay/1’, { signal: ctl.signal }); if (!r.ok) throw new Error(‘upstream_bad_status’); const data = await r.json(); res.json({ ok: true, data }); } catch (e) { res.status(502).json({ ok: false, error: String(e) }); } finally { clearTimeout(t); } }); app.listen(3000, () => console.log(‘listen 3000’));
コード例2:ブラウザFetch リトライ+指数バックオフ
export async function fetchWithRetry(url, opts = {}, max = 3) {
for (let i = 0; i < max; i++) {
const ctl = new AbortController();
const id = setTimeout(() => ctl.abort(), 1500);
try {
const r = await fetch(url, { ...opts, signal: ctl.signal, cache: 'reload' });
if (r.ok) return r;
} catch (_) {}
finally { clearTimeout(id); }
await new Promise(s => setTimeout(s, 2 ** i * 100));
}
throw new Error('fetch_retries_exhausted');
}
コード例3:Go サーキットブレーカー(sony/gobreaker)
package main
import ( “fmt” “net/http” “time” cb “github.com/sony/gobreaker” )
func main() { st := cb.Settings{Name: “api”, Timeout: 2 * time.Second} br := cb.NewCircuitBreaker(st) body, err := br.Execute(func() (any, error) { c := &http.Client{Timeout: 200 * time.Millisecond} resp, err := c.Get(“https://httpbin.org/delay/1”) if err != nil || resp.StatusCode >= 500 { return nil, fmt.Errorf(“upstream”) } return “ok”, nil }) if err != nil { fmt.Println(“fallback”, err); return } fmt.Println(body) }
コード例4:Python タイムアウト+フォールバック
import requests from requests.exceptions import RequestException
def get_user(uid: str): try: r = requests.get(f”https://api.example.com/users/{uid}”, timeout=0.2) r.raise_for_status() return r.json() except RequestException as e: return {“id”: uid, “name”: “unknown”, “fallback”: True, “error”: str(e)}
if name == “main”: print(get_user(“42”))
コード例5:k6 シナリオ(遅延注入下のSLI計測)
import http from 'k6/http'; import { sleep } from 'k6';
export let options = { vus: 20, duration: ‘1m’ }; export default function () { const res = http.get(
${__ENV.TARGET || 'http://localhost:3000/api'}
); if (res.status >= 500) { console.error(‘server_error’); } sleep(0.1); }
コード例6:Kubernetes PDBと故障注入(レイテンシ)
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata: { name: api-pdb }
spec:
minAvailable: 90%
selector: { matchLabels: { app: api } }
---
apiVersion: apps/v1
kind: Deployment
metadata: { name: toxiproxy }
spec:
replicas: 1
template:
metadata: { labels: { app: toxiproxy } }
spec:
containers:
- name: toxiproxy
image: ghcr.io/shopify/toxiproxy:2.6
観測とアボート条件の実装ポイント
- SLI集約:BEはp50/p95/p99レイテンシ、エラー率、サチュレーション(CPU/メモリ)。FEはp95 LCP/INP、JSエラー率。
- アボート自動化:PrometheusアラートでカナリアWeightを0に自動反映。閾値はエラー率>2%かつp95>2×基準のいずれか。実験自動化はカオス実践ガイドにも合致¹⁴。
- 学習:事後レビューで「仮説→観測→改善PR→再検証」を1サイクル2週間で回す²。
ベンチマークとビジネス効果
小規模パイロットの結果(例)
前提:/apiの平常時p95=120ms、エラー率0.2%。k6でRPS≈180(20 VU, 1m)。toxiproxyで上流に+300ms遅延を30%の確率で注入。
シナリオ | p95(ms) | エラー率 | 可用性(%) |
---|---|---|---|
Baseline | 120 | 0.2% | 99.8 |
遅延注入(無対策) | 780 | 6.1% | 93.9 |
対策適用(Timeout+CB) | 210 | 1.3% | 98.7 |
Timeout+CBでp95を大幅改善、エラー率を低減。SREの考え方では、こうした実験結果をSLO/エラーバジェットに接続し、変更速度とのトレードオフを管理します²。
ROIの概算と導入期間
- ダウンタイムコスト:分間売上100万円のSaaSで、月2回×20分の障害=4,000万円/月(仮定)。
- カオス導入コスト(パイロット2スプリント):人件費600万円+ツール/環境30万円=630万円。
- 効果:Timeout/CB/Retry最適化で障害時間を50%削減と仮定→2,000万円/月の回避。初月ROI=(2000-630)/630≈217%。仮定は各社のSLO/トラフィックに合わせて補正してください²。
導入期間の目安は、設計1週、実装1〜2週、実験/学習1週。以後は月1回のゲームデイで継続的改善を回すのが標準です¹。
ベストプラクティス(フロントエンド重点)
- 第三者スクリプトはdefer+timeout+onerrorで隔離。失敗時は機能フラグで即時無効化。
- Service Workerでスタティックをstale-while-revalidate。APIは短TTLキャッシュ+フォールバックUI。
- Retryは冪等なGETのみに限定、指数バックオフ+ジッタ、上限3回。ユーザー操作は明示的再試行⁷。
- Edgeでのフェイルオープン戦略(部分的に壊れても主要パスを守る)。
まとめ
故障は避ける対象ではなく、制御して学習する対象です¹。SLOとエラーバジェットを軸に、ブラスト半径1%の小さな実験から始めれば、ユーザー体験を守りつつ回復力を高速に高められます。本稿の早見表、6つの最小コード、ベンチマーク/ROI指標をそのままテンプレートとして使い、次のスプリントで「Timeout・CB・Retry」三点セットを標準化してみてください。次にどの故障モードを可視化したいか、そしてその検証を誰がいつ回すか——その問いに答えた瞬間から、信頼性は定常的に成長を始めます。
参考文献
- AWS Prescriptive Guidance. Chaos engineering on AWS: Getting started. https://docs.aws.amazon.com/prescriptive-guidance/latest/chaos-engineering-on-aws/getting-started.html#:~:text=organizations%20that%20conduct%20chaos%20engineering,TBT
- Google Cloud Blog. Good housekeeping: Error budgets—SRE life lessons. https://cloud.google.com/blog/products/devops-sre/good-housekeeping-error-budgetscre-life-lessons#:~:text=For%20a%20rolling%2030,29%20and%20five
- Gremlin. Chaos Engineering Glossary: Blast Radius. https://www.gremlin.com/docs/resources-glossary#:~:text=The%20subset%20of%20a%20system,discrete%20parts%20of%20the%20system
- Gremlin. Chaos Engineering Glossary: Abort Conditions. https://www.gremlin.com/docs/resources-glossary#:~:text=Abort%20Conditions
- SRE School. Error Budgets: A Complete Guide. https://sreschool.com/blog/error-budgets-a-complete-guide/#:~:text=%3E%20Error%20Budget%20%3D%20100,%E2%80%93%20SLO%20target
- LogicMonitor. What’s the Difference Between MTTR, MTTD, MTTF, and MTBF? https://www.logicmonitor.com/blog/whats-the-difference-between-mttr-mttd-mttf-and-mtbf#:~:text=MTTD%20stands%20for%20mean%20time,MTTD%20can%20be
- codecentric. Resilience design patterns: Retry, Fallback, Timeout, Circuit Breaker. https://www.codecentric.de/knowledge-hub/blog/resilience-design-patterns-retry-fallback-timeout-circuit-breaker#:~:text=In%20electronics%2C%20a%20circuit%20breaker,unavailable%20due%20to%20high%20load