分散システム(SoS)における戦略的負荷テスト〜なぜ「とりあえず全APIに負荷をかける」と本番で死ぬのか〜
実証実験(PoC)フェーズを終え、いよいよ社会インフラとしての本番稼働を迎える巨大な分散システム(System of Systems: SoS)。
給付金の申請や大規模な決済プラットフォームなど、絶対に止めることが許されないミッションクリティカルな環境において、「負荷試験」は最後の砦となります。
しかし、多くのプロジェクトが負荷試験のアプローチを根本から間違え、
「テスト環境ではオールグリーンだったのに、リリース初日に本番環境がシステムダウンする」
という悲劇を繰り返しているのではないでしょうか?
本稿では、過去の大規模案件でのビジネスアーキテクトの視点から、ツールによる単なる「実行」の前に必須となる
「ドメインモデルに基づく最上流の負荷試験戦略」
と、なぜその思考を怠るとシステムが破綻するのかを超詳細に解説します。
1. なぜ「絨毯爆撃テスト」は本番環境を殺すのか?
「とりあえず本番相当の環境を立てて、全APIに対して一律に負荷をかけてみよう」。
これは、過渡期のプロジェクトが陥る最も危険なアンチパターン、通称 「絨毯爆撃テスト」 です。
この発想を踏まえないと何が起きるか?(不作為の代償)
このアプローチを許容すると、プロジェクトに「偽の安心感」と「財務リスクの爆発」をもたらします。
一律にAPIを叩くテストは、現実世界のトラフィック(ユーザーの行動)を一切反映していません。
現実のビジネスでは、「全APIが均等に呼ばれる」ことなどあり得ず、特定の業務フロー(例:キャンペーン時の決済、朝9時の打刻など)にアクセスが極端に偏ります(Skewed Load)。
なのにもかかわらず絨毯爆撃テストを行うと、以下のような致命的な結末を迎えます。
1. インフラコストの無自覚な焼却
SoS環境でのフルスペックのノード稼働は、クラウドの従量課金を文字通り「燃やす」行為です。
月に数回しか呼ばれないマスタ参照APIのために巨大なインスタンスを立ち上げ、予算を食いつぶします。
2. 「偽のボトルネック」への過剰投資(Over-engineering)と、真の急所の見落とし
非現実的なトラフィックパターンのせいで「ビジネス上はどうでもいい裏側システムのDBロック」を致命傷と誤認し、チューニングに数週間を浪費します。
その結果、本当に負荷が集中する「外部システムとの連携API」のコネクション枯渇を見落とし、リリース当日にそこからシステム全体が崩壊します。
【結論】
「全APIに負荷をかける」という思考停止は、予算と時間を浪費した挙句、本番のスパイクアクセスには全く耐えられない「見掛け倒しのシステム」を生み出します。
2. SoS環境での戦略的なテスト計画:「高速道路の渋滞予測」アナロジー
外部の自治体、金融機関、独立したサービス群が絡み合うSoS環境において、テストのROI(投資対効果)を最大化するには、「ビジネス上の急所」と「システム上の結節点」を掛け合わせた戦略的絞り込みが不可欠です。
なぜこの考えで行かないとダメなのか?
分散システムにおいて、すべての通信パスを網羅的にテストすることは数学的に不可能です(組み合わせ爆発)。
だからこそ、イベントストーミング等のドメインモデルを駆使し、「どこがボトルネックになり得るか」をアーキテクチャの構造から演繹(推論)しなければなりません。
高速道路でアナロジー
これを「高速道路の渋滞予測」のアナロジーで計画します。
ステップ1:ビジネス上の急所(いつ、どこに車が殺到するか?)
「特定の給付金申請の開始日の午前9時」など、絶対に落としてはならないトラフィック爆発のタイミングを特定します(=お盆の帰省ラッシュ)。
ステップ2:システム構造上の結節点(どこで荷物が重くなるか?)
「どの集約(Aggregate)間の通信が、最も重いペイロードを運んでいるか」を特定します。
巨大なJSONが飛び交う箇所は、ネットワーク帯域とCPU(シリアライズ)を激しく消費します(=大型トラックが集中する料金所)。
ステップ3:テスト計画のROI最大化
上記を掛け合わせ、「お盆のラッシュ時」に「大型トラックが集中する料金所」の負荷をピンポイントで予測し、そこにテストリソースの80%を投下します。
3. 「集約の境界」から負荷を予測し、コントラクト設計へ繋げる
システムに負荷をかける前に、そもそもドメインモデル上の「データの持ち方・送り方」の設計不良を見抜き、リファクタリングする必要があります。
この発想を踏まえないと何が起きるか?(アーキテクチャの隠蔽)
この視点を持たずに「インフラのオートスケール」で負荷を解決しようとすると、「アーキテクチャの設計不良に、毎月数百万のクラウド代を払い続ける」という地獄に陥ります。
スケールアウトにはDBのコネクション数(IOPS)という物理的限界があり、いずれ必ずシステムは詰まります。
だからこそ、以下のようにイベント駆動における「コントラクト(契約)設計」を、負荷とデータ品質のトレードオフから評価しなければなりません。
パターンA:Fat Event(情報のスナップショット全送信)
ある集約の全データを丸ごとイベントメッセージとして後続に送りつける設計です。
データの完全性(メリット)
受信側は必要な情報がすべて揃っているため、送信側にデータを再取得(Query)しに行く必要がなく、自律的に稼働できます。
負荷と不整合リスク(デメリット)
ペイロードが巨大化して通信帯域を圧迫します。
キューの処理遅延を招き、「システム間でデータが不整合になっている時間(Eventual Consistencyの遅延)」が致命的に長期化します。
パターンB:Thin Event(軽量な通知のみ)
「ID:123のステータスがAからBに変わった」という最小限の事実だけを送り付ける設計です。
負荷の軽減と整合性(メリット)
ペイロードが極めて軽く伝達速度が最速になるため、「不整合の時間」は極小化されます。
データの不完全性(デメリット)
受信側は「何が変わったか」しか分からず、詳細情報をFetchしに行く必要があります。
もし相手のAPIがダウンしていると必要な情報が揃わず、業務の意思決定がストップするリスクを抱えます。
【アーキテクトの思考】
負荷試験は「Fat Eventで作られた重いコードに無理やり耐えさせる」ためのものではありません。
「ここはトラフィックが集中するからThin EventにしてFetch型にしよう」
「ここは相手先が落ちていても自律稼働したいからFat Eventにしよう」
という、境界づけられたコンテキスト間の最適化の根拠にするのです。
4. エラーハンドリングと負荷試験(レジリエンスの証明)
負荷試験の最も重要な目的は、「システムがダウンしないことを証明する」ことではなく、「限界を超えた時に、どう安全に倒れるか(Graceful Degradation)」のメカニズムを検証することです。
負荷の閾値の探索メカニズム
戦略的負荷試験では、トラフィックを段階的に上昇させながら以下の閾値を探索します。
通常稼働帯
リソースに余裕があり、レイテンシが安定している状態。
劣化稼働帯(Degradation)
レイテンシが急増するが処理は完了している状態。
※ここでサーキットブレイカー等の防衛機構が発動すべきライン
崩壊帯(Failure)
タイムアウト等が多発し、ビジネス要件が成立しなくなる状態。
STAMP/STPAを用いた安全制御構造のモデル化
システムが「崩壊帯」に突入した際、何も考えられていないシステムは二重決済等のハザードを引き起こします。
ここでSTAMP/STPA(システム理論事故モデル)を用いて「アンハッピーパス」をモデル上で洗い出します。
コントロールアクションの欠落
Webサーバーダウン時、決済キューに入ったメッセージはどうなるか?
不適切なコントロールアクション
タイムアウト時の自動リトライが「リトライストーム」を引き起こさないか?
これらのリスクに対し、サーキットブレイカーの開放や、二重処理を防ぐIdempotency Key(冪等性キー)といった「システムを安全に倒す(守る)メカニズム」を実装します。
ログデータの要件定義(倒れたことの証明と原因分析)
最後に「想定通りに安全に倒れたか」を事後検証するため、アウトプットである「ログデータ」の要件定義が不可欠です。
トレースIDの貫通
SoS環境では入り口から出口まで貫通するTrace IDを付与する。
ビジネスコンテキストの付与
「どの加盟店の、どのユーザーのトランザクションか」というドメイン情報(Business Entity ID)を構造化ログとして出力する。
事後検証のサイクル
ログを集計し「二重決済が起きていないか」「サーキットブレイカーは正確に開いたか」を分析。想定と異なれば、STAMPモデルの欠陥として修正サイクルへ回す。
結論:負荷試験はビジネスアーキテクチャの検証である
「負荷試験」を、単なるインフラやサーバーの強度テストだと捉えているうちは、真の社会インフラを支えることはできません。
ビジネスの急所を予測し、ドメインモデルの境界を最適化し、万が一の崩壊時にビジネスプロセスを安全に守り抜く仕組みを設計する。
負荷試験とは、コードの検証ではなく「ビジネスアーキテクチャそのものの堅牢性を証明する行為」なのです。
システムが複雑化・巨大化するこれからの時代において、この「上流から負荷とレジリエンスをコントロールする」思考こそが、真のROIを生み出す鍵となるでしょう。