前置き
TDD(テスト駆動開発)だけでは、サーキットブレーカーの適切な閾値(スレッショルド)を決めることは不可能です。
TDDはサーキットブレーカーの 「ロジック」(例:CLOSEDからOPENに正しく遷移するか)を検証するには完璧ですが、「本番環境の動的な振る舞い」(例:どの程度の失敗率でOPENにすべきか)を決定するためのものではないからです。
カオス実験は優れたデータ駆動の方法ですが、それ以外にも閾値を決定・調整するための主要なアプローチがあります。
閾値を決定する主なアプローチ
1. 負荷テスト (Load Testing) 🏋️
これがカオス実験と並んで最も一般的で効果的な方法です。
方法
テスト環境(Stagingなど)に対して、意図的に大量のリクエストを送り付け、下流のサービスがどれくらいの負荷で不安定になり始めるか(レイテンシーの悪化、エラー率の上昇)を観測します。
閾値の決定
システムが「危険水域」に入る手前のポイント(例:エラー率が20%を超えると急激に応答不能になる)を特定し、それを基に閾値を設定します。
2. 過去のメトリクス/インシデント分析 📊
すでに稼働しているシステムであれば、過去のデータが最高の教科書になります。
方法
過去に発生した障害(インシデント)の前後のメトリクス(エラー率、レイテンシー)を分析します。
閾値の決定
「障害発生の5分前から、エラー率が30%を超えていた」というような 事実(前兆) を発見できれば、それを閾値(あるいはアラートの基準)として設定します。
3. 経験則による初期設定 🎓
新しいシステムでデータがない場合、まずは業界の ベストプラクティス(経験則) から始めます。
方法
「まずはこのくらいで始めてみよう」という共通の初期値を設定します。
閾値の例
・失敗率:過去1分間で 50% 以上
・タイムアウト:3秒
・Open状態の持続時間:30秒
重要
これはあくまで出発点です。
デプロイ後、すぐに 次のステップ(継続的な調整) に移る必要があります。
4. 継続的な観測と調整 📈
最も重要なアプローチです。閾値は「一度決めたら終わり」ではありません。
方法
運用を開始した後、オブザーバビリティツールで実際のトラフィックとサーキットブレーカーの動作を常時監視します。
閾値の調整
・「ブレーカーが頻繁に開きすぎる(閾値が厳しすぎる)」→ 閾値を緩める。
・「システムが不安定なのにブレーカーが開かない(閾値が甘すぎる)」→ 閾値を厳しくする。
・ビジネスの閑散期と繁忙期で、閾値を動的に変更する(アダプティブな閾値設定)こともあります。
まとめ
結論として、 サーキットブレーカーの閾値設定は、TDDのような静的なテストではなく、
負荷テストや過去のデータ分析、そして何よりも本番環境での継続的な観測といった、
データ駆動のアプローチによって決定・改善され続けるものです。
負荷テストで検証すべき重要なシナリオ
流れるデータのサイズ感が大きいユースケース(例:巨大なファイルアップロード、非常に重いJSONレスポンス)は、負荷テストで検証すべき重要なシナリオの一つです。
しかし、負荷テストはそれだけではありません。
主な目的は、システムがさまざまな「高負荷」に耐えられるかを見ることであり、その「負荷」には大きく分けて2つの種類があります。
1. リクエストの量(スループット)による負荷 (最も一般的)
これは、負荷テストと聞いて多くの人が最初に想像するものです。
シナリオ
データのサイズは小さい(例:数KBのAPIリクエスト)が、1秒間に何千リクエストも来る。
あるいは 何万もの同時接続 が発生するケース。
例
・ECサイトのセール開始時の「カートに入れる」リクエスト。
・SNSのタイムラインの集中アクセス。
主な検証対象
・CPU使用率(リクエスト処理)
・スループット (RPS - Request Per Second)
・レイテンシー(応答時間)
アナロジー
「レジに100人が並び、全員がたったガム1個だけを買う」状態。
レジ係(CPU)の処理速度そのものが試されます。
2. 「データのサイズ(重量)」による負荷
シナリオ
リクエストの「数」は少なくても、1リクエストあたりのデータサイズが非常に大きい(例:数百MB〜数GB)ケース。
例
・高解像度の動画や画像のアップロード。
・大規模なレポート(Excel/PDF/CSV)のダウンロード。
・AIモデルの学習データの送受信。
主な検証対象
・メモリ(RAM)使用量(巨大なデータを一時的に保持できるか)
・ネットワーク帯域(帯域を使い果たしていないか)
・ディスクI/O(ストレージへの書き込み・読み出し速度)
アナロジー
「レジに来たのは3人だけだが、全員が山盛りのショッピングカート2台分を買う」状態。
サーバーのリソース(メモリやネットワーク)が枯渇しないかが試されます。
結論:ボトルネックの特定
負荷テストの最終的な目的は、システムの 「ボトルネック(制約)」 を見つけることです。
・シナリオ1(量)では、CPUがボトルネックになるかもしれません。
・シナリオ2(サイズ)では、メモリやネットワークがボトルネックになるかもしれません。
優れた負荷テストは、「リクエスト量」と「データサイズ」の両方、あるいはその両方が同時に発生する最悪のケース(例:100人が同時に重いファイルをアップロードする)をシミュレートし、システムの限界を明らかにします。
ドメインモデルでペイロードサイズを見積もる
ドメインモデル(特にDDDのエンティティや値オブジェクト)を設計する段階で、
そのユースケースで扱われる属性のみを洗い出していれば、1リクエストあたりのデータサイズ(ペイロードサイズ)の 「おおよそのサイズ感」を見積もることは可能です。
なんでドメインモデルから予測できるのか?を以下で書いていきます。
1. 属性(Attribute)の洗い出し
ドメインモデリングのプロセスでは、そのユースケース(例:「ユーザープロフィール更新」)に必要な属性を定義します。
ユースケース:UpdateUserProfile
ドメインモデル:Userエンティティ
属性:
・userId (String, 36文字)
・username (String, 50文字)
・bio (String, 10,000文字許容)
・profileImage (Base64エンコードされた画像データ, 5MBまで)
2. サイズ感の見積もり
このドメインモデルを見た瞬間に、アーキテクトは「このユースケースは危険だ」と気づくことができます。
userIdやusernameは、サイズとして無視できます。
bio属性
最大10,000文字ということは、これだけで約10KB~30KB(UTF-8の場合)のデータになる可能性があります。
profileImage属性
5MBの画像アップロードを許容する場合、Base64エンコードでデータサイズは約33%大きくなり、リクエストペイロードは約6.7MBに達します。
3. 負荷テストシナリオへの反映
このドメインモデルからの見積もり(=仮説)に基づき、負荷テストのシナリオ(=仮説検証)を設計します。
見積もり(仮説)
「このUpdateUserProfileユースケースは、平均10KB(bio中心)、最大7MB(画像中心)のペイロードを生成する可能性がある。」
負荷テストシナリオ(検証)
・シナリオA (量)
1KBのペイロード(username変更のみ)で、1000 RPSを流す。
・シナリオB (サイズ/重量)
7MBのペイロード(画像+bio変更)で、10 RPSを流す。
結論
ドメインモデリングは、単なるビジネスロジックの整理だけにとどまりません。
その際のポイントは、ユースケース中で使用しない属性は、モデル上に出さないこと。
「どのようなデータが、どれくらいのサイズ感で、どのユースケースで流れるか」
を設計段階で明らかにする活動です。
これにより、アーキテクトは負荷テストを行う前から、
「どのユースケースがメモリやネットワーク帯域(=サイズ)を圧迫しそうか」
をおおよそ予測し、重点的に検証すべきシナリオを特定することができます。