完璧なネットワークでのテストをやめる:Chaos Tunnelsとローカルネットワーク劣化の新しい手法

完璧なネットワークでのテストをやめる:Chaos Tunnelsとローカルネットワーク劣化の新しい手法
ローカルで開発しているとき、あなたの fetch() リクエストはインターネットを越えません。ループバックインターフェースに直接アクセスし、ジッターや輻輳、信号干渉もありません。この無菌環境では、レースコンディションは隠れたままですし、ローディングスピナーも一瞬だけ点滅するだけで完璧に見えますし、リトライロジックも実際にはリトライしていません。そこから本番環境にリリースすると、現実が待ち受けています。
ゼロレイテンシのlocalhost上でソフトウェアを構築するのは、浴槽の中で潜水艦をテストするようなものです。コンポーネントは孤立して動作しますが、実際の圧力に耐える様子はわかりません。これを解決するのが localhost上のChaos Engineering です。
Practitionersが今呼んでいる “Chaos Tunnels” — ローカル接続を意図的に劣化させるプロキシ — を導入することで、コードの一行も本番に到達する前に、UIのエラーハンドリング、状態管理、リトライロジックをストレステストできます。
実際のネットワークはローカルホストとは全く異なる
ツールの詳細に入る前に、データに基づいて理解しておく価値があります。2026年2月に公開された、5Gスタンドアロン(SA)と非スタンドアロン(NSA)パブリックネットワークの比較調査によると、NSA 5Gは平均約54msの遅延を示し、ジッターはプライベートなSAネットワークの約10倍に近く、50msを超えるスパイクも散見されました。
あなたのlocalhostのラウンドトリップは? 亜ミリ秒です。その差 — 127.0.0.1の無菌ループと、公開モバイルネットワークの敵対的な現実との間にあるギャップ — こそがバグの温床であり、ユーザの信頼を失わせる原因です。
Chaos Engineeringは、そのギャップを意図的に埋めるための、制御された実験の discipline です。
2026年に実際に使われているツール:何が使われているのか
Toxiproxy:現場の主力
最も広く採用されているローカルネットワーク劣化ツールは Toxiproxy です。これはShopifyが自社インフラの耐障害性テストのために作ったTCPプロキシフレームワークです。2025年の学術調査によると、GitHubの971リポジトリの中で、Toxiproxy、Chaos Mesh、NetflixのChaos Monkeyがchaos engineeringツールを使うリポジトリの合計64%以上を占めており、Toxiproxyはエコシステムのトップ3に入っています。
Toxiproxyは言語に依存せず、Goのバイナリ一つで提供され、HTTP管理APIも公開しており、テストコードやCIスクリプトからの制御も容易です。
Chaos Tunnelの設定は簡単です。 例えば、バックエンドAPIが localhost:3000 で動いているとします。localhost:4000 にプロキシトンネルを作り、Toxiproxyを経由させ、そのトラフィックに「toxics」 — ライブラリの用語で設定可能な故障条件 — を注入します:
# Toxiproxyサーバーを起動(コントロールプレーンはポート8474)
toxiproxy-server
# ポート4000からAPI(ポート3000)へのプロキシを作成
toxiproxy-cli create my_api -l localhost:4000 -u localhost:3000
# 1000msの遅延と500msのジッターを注入 — 混雑した4G接続を模擬
toxiproxy-cli toxic add -t latency -a latency=1000 -a jitter=500 my_api
# もしくは完全に切断 — データベースのクラッシュを模擬
toxiproxy-cli toxic add -t timeout -a timeout=0 postgres_proxy
Toxiproxyは複数のtoxicsタイプを標準でサポート:latency、帯域制限、slow_close(接続が閉じる前にハングする模擬)、reset_peer(TCPリセット)、limit_data(Nバイト後に切断)です。これらはアップストリームまたはダウンストリーム方向に独立して適用可能です。
Testcontainersとの連携: Java、Node、Python向けにネイティブのToxiproxyモジュールを提供するツールもあります。これにより、Docker上に実際のデータベースを立ち上げ、chaos proxyでラップし、クエリを実行し、ネットワークを意図的に切断し、アプリが正しいエラーを投げるかを自動化されたCI/CDパイプライン内で検証できます。
Trixter:新しいRustベースの代替
2025年10月にリリースされた、より高性能でセットアップが簡単な選択肢として注目されているのが Trixter です。Rustのasync Tokioフレームワークを用いて書かれた高性能なchaosプロキシで、TCP層のネットワーク障害を注入します。tc netem(Linuxのカーネルレベルのトラフィック制御)とは異なり、root権限や特別なネットワーク設定は不要です。サービスのアドレスを指定するだけで、そのトラフィックだけにchaosを適用します。
Trixterはランタイムでパラメータ調整も可能:接続ごとに障害パラメータを動的に変更でき、再起動不要です。REST API経由で設定可能です。バイナリは3.3MBと小さく、すべてのテストスイートに簡単に導入できます。KubernetesのポッドやmacOS/Windowsの開発マシン、rootアクセスが不要なCIパイプラインに最適です。
# Trixterをプロキシとして起動:8080で待ち受け、上流サービスは3000
# 1%の接続終了と1%のパケット破損を設定
docker run --network host -it --rm ghcr.io/brk0v/trixter \
--listen 0.0.0.0:8080 \
--upstream 127.0.0.1:3000 \
--api 127.0.0.1:8888 \
--terminate-probability-rate 0.001 \
--corrupt-probability-rate 0.01
このパターンはchaosを 決定論的かつ再現性のあるものに します — ネットワーク層の性質ベーステストです。
アプリケーション層のChaos:HTTP改ざん
TCPレベルのプロキシは純粋なネットワーク劣化には最適ですが、現代のUI開発では アプリケーション層(Layer 7) のchaosも必要です — HTTPトラフィック自体を改ざんします。
チームは今や カスタムChaos Proxyエージェント を構築または利用しています。これらはローカルAPIの前に直接配置され、HTTPトラフィックをインテリジェントに変異させることが可能です。
502 Roulette。 プロキシを設定して、GraphQLのミューテーションの15%で 502 Bad Gateway をランダムに返すようにします。これにより、フロントエンド開発者は堅牢な自動リトライロジック — 通常は指数バックオフとジッター — を実装し、UIが意味のあるエラーを表示することを確認できます。
Silent 401。 アプリの認証トークン期限切れの処理は、多くの設計ミスの一つです。APIが 401 Unauthorized を返したとき、適切に設計されていないアプリはユーザを強制的にログイン画面にリダイレクトし、未保存のフォーム状態を失います。Chaos Proxyは有効なリクエストを傍受し、Authorization ヘッダーを削除して 401 を強制します。これにより、開発者は「サイレントリフレッシュ」ロジックを調整できます:401をキャッチし、送信待ちのリクエストを一時停止、バックグラウンドで新しいトークンを取得し、失敗したリクエストを再送し、ユーザに気付かれずに続行させる。ローカルでこのシナリオを注入しないと、そのロジックはほぼテストできません。
レスポンスのファジング。 より高度なプロキシ — 2025年12月に発表されたCI/CDパイプライン用のChaos Proxy APIも含む — は、JSONレスポンス本文を自動的に改ざんし、アプリケーションが異常なデータを受け取ったときの挙動を検証します。これは、サードパーティAPIからの予期しないスキーマ変更に対するパーサやデータマッパの耐性テストに特に有効です。
Playwrightを使ったE2EテストへのChaosの導入
2025-2026年の最大の変化は、chaosテストが手動の開発者ワークフローから自動化されたCI/CDパイプラインへと移行し、 PlaywrightやCypressのようなE2Eテストフレームワークと直接連携していることです。
Playwrightの組み込み page.route() APIは、ブラウザレベルでネットワークをインターセプトし、実際のユーザの動きの中で特定のルートに対して劣化条件をシミュレートできます — 外部プロキシの設定は不要です。
// Playwrightテスト例:決済処理が突然のネットワークタイムアウトを乗り越える
test('決済は突然のネットワーク切断に耐える', async ({ page }) => {
await page.goto('/checkout');
await page.fill('#credit-card', '4242 4242 4242 4242');
// 支払いAPI呼び出しをインターセプトし、10秒のタイムアウトをシミュレート
await page.route('**/api/payment', async route => {
await new Promise(f => setTimeout(f, 10000));
route.abort('timedout');
});
await page.click('#submit-payment');
// UIがタイムアウトを適切に処理しているか検証
await expect(page.locator('#payment-status')).toHaveText('ネットワーク遅延。再試行中...');
await expect(page.locator('#submit-payment')).toBeDisabled();
});
このテストは、決済フローという重要なユーザージャーニーがネットワーク障害に耐え、データ損失や二重課金を防ぐことを保証します。すべてCI上でプルリクごとに自動実行され、リグレッションも検知します。
ネットワーク障害だけでなく、Tokenの有効期限切れ(上記のSilent 401)、フォーム送信中の不正なAPIレスポンス、部分的なページ読み込み(リソースの一部だけ成功)もシミュレートしています。
Chaos EngineeringがUIに求めること
ローカルChaos Tunnelの導入は、バグを捕まえるだけではありません。UIエンジニアのアーキテクチャ観を根本的に変えます。
1. オプティミスティックUI — 正直なロールバックとともに
開発者が頻繁にローカルAPIのタイムアウトを経験すると、サーバを待たずにUIを更新する Optimistic UI を採用します。例:いいねしたハートや投稿済みコメントを即座に表示し、サーバの応答と整合させる。しかし、Chaos Proxyが最終的にリクエストを失敗させると、ロールバックの仕組みを作る必要が出てきます。UIの状態を元に戻し、ネットワークが永続的に落ちたときに通知を表示します。Chaosテストがなければ、そのロールバックパスはほとんど書かれず、テストもされません。
2. アイデンポテンシーをデフォルトに — 後付けではなく
Chaos Tunnelが激しいジッターを導入すると、リクエストが遅延しすぎて、フロントエンドは失敗とみなして再試行します。同じアクションを二重に送信してしまうことも。もしAPIに idempotency keys(一意のトークン)を実装していなければ、重複したエントリがローカルDBに記録されることになります。Chaos Proxyは正しいAPI設計を強制します。実用的なガイドによると、分散システムではアイデンポテンシーは必須です。
3. 無限スピナーの終焉
パケットロスや遅延による接続遅延は、ユーザの信頼を最も早く失わせる要因です。ローカルでパケットロスや遅延を注入し、積極的なクライアント側タイムアウトを設定します。8秒以内に応答がなければ、UIはリクエストを中断し、「再試行」ボタンを表示。これらのパターンはPlaywrightのテストに組み込み、コミットごとに実行可能です。
4. スムーズな決済とチェックアウト
Chaos EngineeringはECサイトでは特に重要です。決済ゲートウェイのタイムアウトや無効な割引コード、OTP失敗をシミュレートし、UIにこれらのケースを明示的に処理させます。カートの内容を保持し、エラーメッセージを表示し、重複支払いを防ぐ。これらは本番での損失や離脱の原因となる失敗モードです。
実践的な始め方
複雑なインフラ変更は不要です。今日から導入できる最小限のワークフローは以下です:
- Toxiproxyをインストール(macOSなら
brew install toxiproxy、またはバイナリをダウンロード)し、toxiproxy-serverを起動 - ローカルバックエンドに向けたプロキシを作成。開発中のフロントエンドを実際のバックエンドの代わりにプロキシポートに設定
- 必要な故障モードごとにtoxicsを追加:遅延、タイムアウト、帯域制限など
page.route()を使ったPlaywrightテストを作成:決済や認証、フォーム送信などの重要なユーザージャーニーがタイムアウトに耐えるか検証- CIでこのテストを実行:プルリクごとに自動化
最もコストのかかる失敗モードから始めましょう。SaaSなら決済フロー、ソーシャルアプリなら投稿フロー、データ系ならエクスポートやレポート生成です。
結論:敵対的なネットワークを受け入れる
分散型・モバイルファーストの世界では、ゼロレイテンシのlocalhostは幻想です。実際の5Gは、プライベートネットワークの10倍以上のジッターを示します。ユーザは電車やトンネル内、Wi-Fiからセルラーに切り替えたり、電波の弱い建物に座ったりしながらフォームを送信します。その体験はミリ秒ではなく、フラストレーションやデータ損失、セッション放棄で測られます。
Chaos Tunnels — Toxiproxyの toxic API、Trixterの軽量Rustプロキシ、Playwrightのrouteインターセプトなどを使って、完璧な接続の幻想を体系的に崩壊させましょう。遅延スパイクのローカルテスト、ランダムな 502エラーの注入、途中での接続切断:これらはもはやSREのニッチな作業ではありません。UIエンジニアリングにとって、信頼してリリースするための最低条件です。
今日、ローカル環境を破壊し、明日のユーザのためにアプリケーションを堅牢にしましょう。
Related Topics
Keep building with InstaTunnel
Read the docs for implementation details or compare plans before you ship.