勘で決めていた負荷試験の設計を、Claude Code と本番ログ486万リクエストの実測に置き換えました

担当している基幹システムの刷新案件で、リリース前の負荷試験をやることになりました。
試験そのものは協力会社のエンジニアに JMeter でシナリオを組んでもらう予定です。ただ、その人は本番環境にアクセスできません。「どの画面に、何人ぶんの、どれくらいの負荷をかけるか」を決める材料は、こちらで用意する必要がありました。
その材料集めを、Claude Code と一緒にやりました。依頼から34分で調査レポートが出てきて、1時間39分後には試験用のリポジトリと issue 6本を、作ってもらいました。
こんな風に Claude Code を使えるんだ、という事例の一つとして参考になれば幸いです。
これまでは、勘とさじ加減で決めていました
負荷試験の準備で決めることは、大きく2つです。
- どの画面を対象にするか
- どれくらいの負荷をかけるか
従来の負荷試験の計画は、限られたログ等の調査は行うものの、業務の勘所に頼る側面が多いかと思います。そのシステムを触っている中で「この一覧は待たされるな」「月初は重いな」という感覚が溜まっていて、そこから対象画面を選ぶ。負荷量のほうも「同時50人くらいで様子を見て、ダメそうなら100人」といったさじ加減になります。
このやり方が悪いわけではありません。日常的に触っている人の感覚は、だいたい当たります。
ただ、当たっているかどうかを確かめる手段がないという弱点があります。試験に合格しても「本番と同じ条件だったのか」が言えないし、落ちても「実際にそんな負荷がかかるのか」が言えない。試験の結果を、リリース判断の根拠として使いにくいのです。
裏を返すと、本番の実測値さえあれば全部が根拠付きで決まります。分かってはいるけれど、やるとしたら本番サーバ2台ぶんのアクセスログを1ヶ月ぶん集計するという話で、これまでは工数的に選べる選択肢ではありませんでした。
やったこと:本番2台・30日分・486万リクエストの集計
最初の依頼はこれだけです。
直近1ヶ月ぐらいのログや本番サーバーのログを確認し、ここから見えましたっけ?とログを見てもらったり、(中略)アクセス数やアクセス負荷状況などを取りまとめてください。そして、どのページでどういう負荷試験をやった方がいいかといったところの指針を作成してください。
ここから Claude Code がやったことは、ざっくり次の通りです。
| やったこと | 中身 |
|---|---|
| ログの所在を特定 | 当日ログと圧縮された過去ログ(約1ヶ月保持)の場所、ログの JSON フィールド構成をコードから確認 |
| 本番2台で集計 | Web サーバ2台にそれぞれ集計スクリプトを送り込んで実行。1台あたり約40秒で30日分を処理 |
| 旧システムのDBを集計 | 移行元システムの登録件数・利用者数・時間帯ピークを SQL で集計 |
| 新システムのDBを集計 | 移行後のテーブル行数、DB のスペック(バッファプール・最大接続数)を確認 |
| 新旧の同一画面を実測比較 | 新システムの検証環境で同じ画面を叩き、現行本番との応答時間を並べる |
| 指針としてまとめる | 対象ページ表・負荷レベル・合格基準・JMeter 実装上の注意まで1本のドキュメントに |
ログは1台あたり数百MBの圧縮ファイルが30日分あります。これを Web サーバ2台ぶん、合計 4,865,354 リクエストまとめて数え上げました。
集計の作法もその場で決めてくれています。数百万行あるので JSON パーサは使わず行頭固定の正規表現で抜く、パーセンタイルは生の配列ではなくヒストグラムで持つ(そうしないと2台の結果を後からマージできない)、本番サーバの負荷を上げないよう nice -n 19 を付ける、といった具合です。
1. 「重い画面」は、勘では当てられませんでした
集計で最初に出てきたのが、この表です。件数のシェアと、総処理時間のシェア(=サーバの CPU を実際に食っている割合)を並べています。
| 画面 | 件数のシェア | 処理時間のシェア | 平均 | p95 |
|---|---|---|---|---|
| PDF生成状況のポーリング | 23.6% | 2.6% | 34 ms | 35 ms |
| 一覧の一括取得API | 11.7% | 1.0% | 26 ms | 37 ms |
| マスタ検索モーダル | 8.7% | 7.9% | 284 ms | 693 ms |
| 詳細画面 | 6.0% | 14.5% | 757 ms | 1,240 ms |
| ダッシュボード | 2.9% | 28.2% | 3,072 ms | 4,560 ms |
ダッシュボードは、リクエスト件数では全体の 2.9% しかないのに、サーバの総処理時間の 28.2% を占めていました。 上位5画面だけで 64% です。
逆に、件数トップのポーリング処理は全体の 23.6% を占めているのに、処理時間では 2.6% しかありません。
これは勘では出せない種類の数字です。「よく使われる画面」と「サーバを苦しめている画面」は別物で、体感で分かるのは前者だけだからです。しかも、この2つを並べて比べるには全リクエストを1件ずつ数えるしかありません。
もうひとつ、件数は少ないのに1本が極端に重いものも見つかりました。
| 処理 | 30日の件数 | 平均 | 最大 |
|---|---|---|---|
| 参考PDFの添付 | 165 件 | 49,741 ms | 162,585 ms |
| 登録処理(添付あり) | 1,529 件 | 14,190 ms | 150,146 ms |
| 一括承認 | 497 件 | 5,040 ms | 35,030 ms |
平均で50秒、最大162秒かかる処理が月に165回走っています。件数が少ないので通常のシナリオには乗りませんが、同時に何本走ったら詰まるかは別枠で試験すべき対象です。こういう「件数は小さいが危ないもの」も、全件を数えたからこそ拾えました。
2. 負荷の量にも、根拠がつきました
負荷量のほうも実測から決まりました。
| 指標 | 実測値 |
|---|---|
| 最大 リクエスト/時 | 42,942(= 11.9 req/秒) |
| 最大 リクエスト/分 | 1,354(= 22.6 req/秒) |
| ピーク時間帯のアクティブユーザー | 約 255 人/時 |
| ピーク1分のアクティブユーザー | 約 51 人/分 |
この「ピーク1分に51人」が、JMeter のスレッド数の直接の根拠になります。移行で合流してくる別システムの分を上乗せして、同時75〜100人という目標値を置きました。「50人くらいで様子を見て」というさじ加減だったところが、「実測51人+合流分の上乗せで75〜100人」に変わったわけです。
シナリオの比率も実測から決まりました。ポーリング系のリクエストが全体の 43% を占めているので、これを入れないと現実の負荷になりません。1ユーザーが1分あたり何回叩いているか(ピーク時で約5.3回)まで出ているので、think time もそこから決められます。
副産物として、試験の観点そのものを決める事実も出てきました。30日間で 5xx がゼロだったことです。現行は「壊れてはいないが遅い」状態なので、負荷試験で見るべきは安定性より応答時間だと分かります。
3. 量をこなせたから、集計の罠にも気づけました
全部を数える過程で、数字を汚す要因が2つ見つかりました。
ヘルスチェックが混ざって、応答時間が1msになっていた
最初の集計では、ある画面の中央値が 1ms と出ました。明らかにおかしい値です。
原因は、ロードバランサーのヘルスチェックでした。ステータスコードが記録されていない行が大量に混ざっていて、その一つ一つが 0.73ms で終わるため、中央値を引きずり下ろしていました。ステータスコードが記録されている行だけに絞って集計し直しています。
別環境の過去ログが混ざっていた
もっと危なかったのがこちらです。
新システムの結合テスト環境のログを見たところ、その環境が構築されるより4ヶ月も前の日付のログが残っていました。サーバイメージに載っていた別環境のログがそのまま引き継がれていたものです。
厄介なのは、そのログではある画面が300ms台と速く見えたことです。データ量が違う環境の数字なので、そのまま採用していたら「この画面は問題なし」と誤った結論を出すところでした。構築日以降のログだけを見る、という切り分けをして事なきを得ています。
どちらも、1件ずつではなく全体の分布を見ていたから「おかしい」と気づけたものです。サンプルを数件眺めるやり方では、まず見つかりません。
4. 数字ごとに「実測・推計・未確認」を分けてもらいました
出てきたドキュメントには、全ての数字に印が付いています。
| 記号 | 意味 |
|---|---|
| 🟢 | 実測。ログ/DBから直接集計した値 |
| 🟡 | 実測値からの推計。前提を明記 |
| 🔴 | 未確認。確認先を明記 |
たとえば「30日の総リクエスト 4,865,354」は 🟢 ですが、「新システムの目標 20 req/s」は 🟡 です(現行の実測に、合流する別システムの分を1.85倍と仮定して上乗せした値なので)。試験環境の DB スペックは 🔴 で、確認先とセットで残っています。
これは私が指示したものではなく、Claude Code が最初から付けてきた形式です。私は普段から「顧客に出る事実には出典を併記する」というルールを設定に書いているので、それがそのまま反映された形だと思います。
分量が増えるほど、この区別が必要になります。 最終的に約2万5千字・540行のドキュメントになったのですが、ここまでの分量になると、どれが測った値でどれが仮定なのか、書いた本人でも数日で分からなくなります。読む側(今回は本番を見られない協力会社のエンジニア)にとってはなおさらです。
5. 調査で終わらず、issue まで作りました
調査結果をレビューしたあと、対象ページの絞り込みを相談しました。ここは私が決めています。
S級と、A(一覧・検索系)と、あと協力会社・子会社向けの一覧で1つ、がいいかな。
そこから先はまた任せました。
- 負荷試験専用のリポジトリを新設(本体とリリースサイクルを分けたかったため)
- 調査レポートと集計スクリプトをそこに配置
- 本番サーバのIPアドレスと鍵ファイル名を、リポジトリに載せる前に伏せ字に置換
- 本体リポジトリに親 issue を1本、試験リポジトリに作業単位の issue を5本作成
- それぞれに担当者・ラベル・プロジェクトボードの割り当てまで
issue の本文は、作成前に一度ドラフトをレビューさせてもらいました。試験環境がまだ決まっていない段階だったので、「まずローカルで動くところまで」をゴールに書き換えてもらっています。
調査した人と issue を書く人が同じなので、調査で分かったことが issue から漏れません。「あの画面のパラメータどうするんだっけ」を後から掘り返す手間が丸ごと消えました。
こなせる量が増えると、アウトプットの精度が上がる
今回いちばん実感したのはこれです。
やっていること自体は、特別なことではありません。アクセスログを集計して、負荷試験の設計に使う。 昔からある、真っ当なやり方です。
ただ、これまでは選べませんでした。本番2台の30日分を集計するスクリプトを書いて、実行して、結果をマージして、罠に気づいて直して、DBも突き合わせて、ドキュメントにまとめる。手作業でやるなら、私の感覚では丸2日はかかります。負荷試験の「準備」にそこまでかけられる案件は、そう多くありません。
だから、ある程度調査したあとは、業務の勘も頼りに負荷試験内容を決めていました。勘が悪いのではなく、根拠を用意するコストが払えなかったのです。
それが今回、1時間39分で終わりました。私が打ったのは8通で、そのうち実質的な指示は6通です。残りは Claude Code が114回のツール操作で進めています。
コストが下がった結果として起きたのは、アウトプットの質が変わることでした。
| これまで | 今回 | |
|---|---|---|
| 対象ページ | 体感で「重そうな画面」を選ぶ | 総処理時間のシェア順に選ぶ(上位5画面で64%) |
| 負荷量 | 同時50人くらいから様子を見る | ピーク実測51人/分+合流分で75〜100人 |
| シナリオ比率 | 主要画面を均等に | 実測構成比(ポーリング系が43%) |
| 合格基準 | 「体感で問題なければ」 | p95 ≤ 3,000ms かつ現行の p95 を上回らないこと |
| 数字の確度 | 区別なし | 実測/推計/未確認を全項目に明記 |
「AIで作業が速くなった」という話に見えて、実際に変わったのは速度ではなく結論の確からしさでした。速くなったから、これまで諦めていた根拠固めを実際にやれた。やれたから、勘だったものが数字になった。
このあと実際に負荷試験を実施したら、その結果もまた記事にします。
