Skip to content

docs: API負荷試験の事前調査結果と試験計画を追加 - #435

Open
taminororo wants to merge 4 commits into
developfrom
docs/kanba/434/load-test-plan
Open

docs: API負荷試験の事前調査結果と試験計画を追加#435
taminororo wants to merge 4 commits into
developfrom
docs/kanba/434/load-test-plan

Conversation

@taminororo

@taminororo taminororo commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

対応Issue

resolve #434

概要

45th 本番前の API 負荷試験に向けた事前調査と試験計画(ドラフト・未実行)を docs/development/load-test-plan.md として追加します。NUTFes Bingo 負荷試験報告書の方法論(原因切り分け、内部直結 vs 公開URL経由の比較、p95/p99 での pass/fail 基準)を踏襲しています。

主な内容:

  • 全74エンドポイントの棚卸し。認証チェックが3箇所のみであることを網羅確認し、実トラフィックのある現役ルートが15本(mobile 9 + GAS 6)に絞られることを呼び出し元コードまで追って確定
  • rescues 統一/個別の並存は移行途中ではなく分業(作成・閲覧=統一/mobile、ステータス更新=個別PUT/GAS)であることの確定
  • 本番 DB(共有 Patroni クラスタ)に向けた試験を最初から除外し、隔離 DB のみで試験する方針とその技術的根拠(DB 接続プール上限未設定など)
  • 当日の実利用に基づく負荷シナリオ3種(朝の一斉アクセス/日中定常/GASバッチ併走)と、k6 による 50→600 VU 段階昇圧・pass/fail 基準
  • 内部直結(Track A)と検証用トンネル経由(Track B)の切り分け設計
  • 後続 issue の提案(環境整備、試験前修正、Track A/B 実行、別トラックの mobile 静的配信対策ほか)

調査で判明した試験計画外のトピック(Access-Token ヘッダ欠落時の panic、POST /request_shifts のデッド化、mobile 静的配信のシングルスレッド問題など)は文書内のリスク・issue 提案節に記録しています。

画面スクリーンショット等

  • ドキュメント追加のみのため無し

テスト項目

  • 文書内の ファイル:行番号 引用が実コードと一致していること(スポットチェックで可)
  • エンドポイント棚卸し表が api/lib/router/router.go の全ルート + /swagger/* を網羅していること
  • 試験計画が「本番DB・本番トンネルに向けない」制約を満たしていること

備考

試験の実行は本 PR のスコープ外です。マージ後、文書 7 章の提案に基づき後続 issue を起票してから着手します。

Summary by CodeRabbit

  • ドキュメント
    • SeeFT本番(45th production stack)向けの負荷試験計画を大幅拡張し、事前調査〜(ドラフト)試験計画〜実測結果(再試験)まで一体化しました。
    • 対象エンドポイント棚卸し、負荷シナリオ(S1〜S3)、Track A/B運用、k6方針、合否基準、認証トークン運用、外部副作用遮断の前提と設定を整理しました。
    • pgbouncer導入やN+1要因など計測条件を追記し、実測結果を追加しました。

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

SeeFT APIのエンドポイント調査、本番構成、負荷シナリオ、k6試験手順、実測結果、判定基準、リスク、後続作業を文書化しています。

Changes

API負荷試験計画

Layer / File(s) Summary
調査範囲とAPI棚卸し
docs/development/load-test-plan.md
試験対象、全エンドポイント、認証挙動、rescues の役割分担を整理。
実行構成と負荷ホットスポット
docs/development/load-test-plan.md
Cloudflare Tunnel経路、DB接続方針、静的配信制約、API・外部連携・ログ出力の負荷要因を記録。
負荷シナリオと試験手順
docs/development/load-test-plan.md
S1〜S3の利用パターン、k6のTrack A/B、段階昇圧、判定基準、認証・副作用遮断手順を定義。
実測結果と後続作業
docs/development/load-test-plan.md
SeeFT-stgでの再試験結果、共有HAクラスタ利用の注記、既知のリスク、前提訂正、後続issue候補を追加。

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning 実測結果の追記など、Issueの「ドラフト・未実行」範囲を超える内容が含まれています。 実測結果の章は別Issueに分離するか、文書を事前調査・計画に限定してください。
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed 主要変更であるAPI負荷試験の事前調査と試験計画の追加を簡潔に表しています。
Description check ✅ Passed 必須の対応Issue、概要、スクリーンショット、テスト項目、備考が埋まっており、内容も具体的です。
Linked Issues check ✅ Passed Issue #434の必須要素(74ルート調査、rescue整理、隔離DB方針、3シナリオ、k6基準、後続Issue提案)を満たしています。
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/kanba/434/load-test-plan

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/development/load-test-plan.md`:
- Line 3:
「作成日」の日付を現在の実際の作成日である2026年7月16日に修正するか、2026年7月17日が予定日であることが明確に分かる表記へ変更してください。
- Line 220: Remove the concrete production IP address from the documentation
sentence near the production configuration reference, and describe the
destination only as the shared Patroni-managed HA cluster. Keep the actual
address exclusively in access-controlled operational documentation.
- Line 266: load-test-plan.md のRPS記述を修正し、300人が5分間に1〜2リクエストを送る前提では平均約1〜2
req/sとして計算する。50〜100
req/sを維持する場合は、数秒以内の集中バーストなど具体的な時間窓と根拠を明示し、DBクエリ量およびVU計画の前提も整合させる。
- Line 327: 明確化する必要があるのは、S2の1
VU・60秒サイクルにおける操作確率モデルです。各エンドポイント操作を排他的な分岐として合計100%になるよう確率を定義するか、独立実行として1分あたりの期待操作回数を明記し、GET
/shift-cards、GET /shifts/tasks/...、レスキュー系、タスク系、POST /rescues、POST
/reviewsの実行条件と回数を再現可能な形に書き直してください。
- Around line 228-230: Clarify the load-test plan that the isolated postgres:18
setup provides only an “API implementation + isolated DB” baseline. Explicitly
state that its results must not be generalized to the production Patroni
cluster, whose hardware, configuration, and shared-resource contention are not
reproduced, while preserving the policy of excluding the shared production
database from load tests.
- Line 449: Update the RESCUE_GAS_URL HTTPS stub setup in the load-test plan to
install a dedicated trusted CA in the test container or configure the HTTP
client’s RootCAs for the self-signed certificate. Ensure POST /rescues succeeds
without TLS errors, and do not use InsecureSkipVerify.
- Line 138: load-test-plan.md
のエンドポイント内訳を表の分類と一致させてください。web_signin・web_signup・web_signoutをadmin(凍結)に含め、GET
/tasksをmobile側に数える前提で、adminを30ルート、デッドルートを27ルートとして本文の集計と説明を更新してください。
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9ae526f5-ac8c-4695-81c8-25e49f9bde74

📥 Commits

Reviewing files that changed from the base of the PR and between 0c0d9c1 and 2dd901a.

📒 Files selected for processing (1)
  • docs/development/load-test-plan.md

Comment thread docs/development/load-test-plan.md Outdated
Comment thread docs/development/load-test-plan.md Outdated
Comment thread docs/development/load-test-plan.md Outdated
Comment thread docs/development/load-test-plan.md
Comment thread docs/development/load-test-plan.md Outdated
Comment thread docs/development/load-test-plan.md Outdated
Comment thread docs/development/load-test-plan.md Outdated
- 本番DB内部IPアドレスの記載を削除し共有Patroniクラスタとのみ記載
- エンドポイント集計のadmin(凍結)/デッドルート数の入れ替わりを修正(30/27)
- 隔離DBの試験結果を本番クラスタへ一般化しない旨を明記
- 300人×5分のRPS試算を修正し、クエリ増幅率とバースト幅の前提を明示
- S2シナリオの操作確率を独立試行として明確化(合計164%の曖昧さを解消)
- RESCUE_GAS_URLスタブのTLS検証(信頼済みCA導入)の注意点を追加
- 作成日の表記を修正
GM・FinanSuはMySQL側(SeeFTはPostgres側)で接続プールは別物であり、
「接続上限の共有」という説明は不正確だった。実際のリスクはMySQL Server・
PostgreSQL・Patroni・etcdが同じ3台の物理ノード上で同居している点にあり、
既知のMySQLスワップ枯渇インシデントを実例として明記した。
インフラ班によるシナリオ①再試験の結果を8章として追記。シフトデータの
分散(1日50件→date_id1〜4に12件ずつ)、pgbouncer導入、N+1修正(PR #438)
それぞれの効果を切り分けて記録。pgbouncerは500エラー・タイムアウトを
解消するが、N+1修正はその後も独立して+31%スループット・約4倍のレイ
テンシ改善をもたらすことを実測。

また、本試験が2.4節の方針(隔離DBのみで試験)から外れ共有HAクラスタ上で
実施された点を確認事項として明記した。

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/development/load-test-plan.md`:
- Around line 541-553:
実測結果の表にp95およびp99の応答時間列を追加し、各負荷条件の実測値を記入してください。値を取得できない場合は、今回の結果を試験計画のpass/fail判定対象外と明記し、平均応答時間のみで判定しないようにしてください。
- Around line 541-553: Align the load-test description and table around the hey
command with the S1 burst model: either replace it with a k6
arrival-rate/stage/parallel scenario that sends 400 users within two seconds, or
explicitly label the current command as steady 200 req/s for 60 seconds. Also
document the hey timeout setting and the criteria used to calculate timeouts.
- Around line 559-560: 「プーラー導入だけで 500
エラー・タイムアウトが全て解消する」という断定を、再試験条件ではタイムアウトが発生しなかった旨の記述に変更する。初回試験と再試験ではシフト分布などの条件が異なるため、pgbouncer単独の因果効果を示さない表現にし、接続数制御がない点と非導入環境で再現しうる点は維持する。
- Around line 562-564: Update section 8.3 and the issue 3・4 execution
prerequisites to require a completed isolated database environment before
testing starts. Remove shared HA cluster use as a normal option; if an exception
is permitted, require explicit approval and resource monitoring.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: fe244907-4565-4007-8f19-142c3f05a1e4

📥 Commits

Reviewing files that changed from the base of the PR and between 879917a and f9be58e.

📒 Files selected for processing (1)
  • docs/development/load-test-plan.md

Comment on lines +541 to +553
`hey -z 1m -c <VU> -q 0.5` で計測。DB プーラーは pgbouncer(`pool_mode=session`、`default_pool_size=50`。`pool_mode=transaction` では DB への通信が溢れたため session モードを採用)。Postgres 本体の `max_connections` は 100。

| プーラー | N+1 | 負荷 | 要求レート | 実測 req/s | 500率 | タイムアウト率 | 平均応答 |
|---|---|---|---|---|---|---|---|
| なし | 未解決 | 400人/2秒 | 約200 req/s | 106.45 | 3.0% | 0% | 3.49秒 |
| なし | 未解決 | 200人/2秒 | 約100 req/s | 97.23 | 7.1% | 0% | 1.41秒 |
| なし | 未解決 | 100人/2秒 | 約50 req/s | 49.06 | 0.4% | 0% | 0.83秒 |
| あり | 未解決 | 400人/2秒 | 約200 req/s | 150.36 | 0% | 0% | 2.40秒 |
| あり | 未解決 | 200人/2秒 | 約100 req/s | 97.63 | 0% | 0% | 1.01秒 |
| あり | 未解決 | 100人/2秒 | 約50 req/s | 49.43 | 0% | 0% | 0.54秒 |
| あり | 解決済 | 400人/2秒 | 約200 req/s | **196.80** | **0%** | **0%** | **0.61秒** |
| あり | 解決済 | 200人/2秒 | 約100 req/s | 99.36 | 0% | 0% | 0.29秒 |
| あり | 解決済 | 100人/2秒 | 約50 req/s | 49.83 | 0% | 0% | 0.16秒 |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

p95/p99を実測結果に追加してください。

試験計画の判定基準がp95/p99である一方、この表は平均応答時間しか記録していません。現状ではpass/fail基準と比較できないため、p95/p99を追加するか、今回の結果は判定対象外と明記してください。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/development/load-test-plan.md` around lines 541 - 553,
実測結果の表にp95およびp99の応答時間列を追加し、各負荷条件の実測値を記入してください。値を取得できない場合は、今回の結果を試験計画のpass/fail判定対象外と明記し、平均応答時間のみで判定しないようにしてください。

🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "## files around load-test-plan"
git ls-files | grep -F 'docs/development/load-test-plan.md' || true

if [ -f docs/development/load-test-plan.md ]; then
  echo "## file size"
  wc -l docs/development/load-test-plan.md
  echo "## relevant lines 520-570"
  sed -n '520,575p' docs/development/load-test-plan.md | nl -ba -v520
  echo "## search hey/k6/S1/load criteria"
  rg -n "hey|k6|S1|バースト|負荷|タイムアウト|時間|秒|req/s|p9?5|p9?9|q =|q " docs/development/load-test-plan.md
fi

echo "## local hey docs if available"
command -v hey || true
if command -v hey >/dev/null 2>&1; then
  hey -h 2>&1 | sed -n '1,120p'
fi

Repository: NUTFes/SeeFT

Length of output: 335


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "## relevant lines 520-570"
sed -n '520,570p' docs/development/load-test-plan.md | awk '{printf "%5d  %s\n", NR+519, $0}'

echo "## search hey/k6/S1/load criteria"
rg -n "hey|k6|S1|バースト|負荷|タイムアウト|時間|秒|req/s|p9?5|p9?9|q =|q |-c|-t|-z|-q" docs/development/load-test-plan.md

echo "## local hey docs if available"
command -v hey || true
if command -v hey >/dev/null 2>&1; then
  hey -h 2>&1 | sed -n '1,120p'
fi

Repository: NUTFes/SeeFT

Length of output: 14114


🌐 Web query:

rakyll hey documentation -c concurrent connections -q requests per second -z duration -t request timeout

💡 Result:

The hey tool (a load generator by rakyll) uses specific flags to control concurrent connections, request rate, duration, and timeouts [1][2]. Concurrent Connections The -c flag sets the number of workers (goroutines) to run concurrently [1][3]. Each worker processes requests in parallel [4]. The default is 50 [1][2]. Requests per Second (Rate Limiting) The -q flag sets a rate limit, defined as the maximum number of queries per second (QPS) per worker [1][3]. Note that this is a per-worker limit, not a global limit [3]. If you specify a duration with -z, the total throughput achieved will be approximately the -q value multiplied by the -c value [5]. Duration The -z flag sets the duration for which to send requests (e.g., -z 10s or -z 3m) [1][2]. When this flag is used, the -n flag (total number of requests) is ignored, and the tool will stop sending requests once the specified duration is reached [1][2]. Request Timeout The -t flag sets the timeout for each individual request in seconds [1][2]. The default value is 20 seconds, and setting it to 0 allows for an infinite timeout [1][6]. Summary of Flags: -c: Number of concurrent workers (default 50) [1][2]. -q: QPS limit per worker (default is no limit) [1][3]. -z: Duration of the test (e.g., -z 30s) [1][2]. -t: Timeout for each request in seconds (default 20) [1][6]. For example, to run a test with 10 concurrent workers at a rate of 5 QPS per worker for 30 seconds, you would use: hey -c 10 -q 5 -z 30s https://example.com [1]

Citations:


S1 のバースト負荷モデルと hey を合わせてください。

hey -z 1m -c 400 -q 0.5 は1ワーカーあたり0.5 QPS、60秒間の定常負荷(約200 req/s)になるので、「400人が2秒以内に一斉アクセスするS1朝バースト」を再現しません。S1 のバースト再現が必要な場合は k6 のarrival rate/stage/parallel 制御を使うか、この行は「定常200 req/s・60秒」へ表記してください。-t / タイムアウト判定条件も併せ明示してください。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/development/load-test-plan.md` around lines 541 - 553, Align the
load-test description and table around the hey command with the S1 burst model:
either replace it with a k6 arrival-rate/stage/parallel scenario that sends 400
users within two seconds, or explicitly label the current command as steady 200
req/s for 60 seconds. Also document the hey timeout setting and the criteria
used to calculate timeouts.

Comment on lines +559 to +560
- **プーラー(pgbouncer)の導入だけで 500 エラー・タイムアウトが全て解消する。** これは 2.4 節が指摘した「API が接続プールの上限を設定していない(`SetMaxOpenConns` 等が存在しない)」問題に対し、DB 側手前にプーラーを挟むことで接続数を吸収した効果である。ただしこれはインフラ側(pgbouncer の設定)の対策であり、SeeFT のリポジトリ・API コード自体は接続数を制御していない状態のままである。プーラーが存在しない環境(`docker-compose.yml` を使うローカル開発環境や CI)ではこの問題は依然として再現しうる
- **N+1 修正(PR #438)は、プーラー導入後もなお独立して効果がある。** 400人負荷で 150.36 → 196.80 req/s(+約31%)、平均応答 2.40秒 → 0.61秒(約4倍)の改善が見られる。プーラーがボトルネックを吸収した後も、1リクエストあたりのクエリ数削減はスループット・レイテンシの両方に寄与することが実測で裏付けられた

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

pgbouncerの因果効果を過大に断定しないでください。

再試験ではpgbouncerなしでも全行のタイムアウト率が0%です。タイムアウト10.4%だった初回試験は、Line 536のとおりシフト分布も変更されています。したがって、「pgbouncerだけでタイムアウトが解消した」とは結論できず、「今回の再試験条件ではタイムアウトが発生しなかった」と記載してください。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/development/load-test-plan.md` around lines 559 - 560, 「プーラー導入だけで 500
エラー・タイムアウトが全て解消する」という断定を、再試験条件ではタイムアウトが発生しなかった旨の記述に変更する。初回試験と再試験ではシフト分布などの条件が異なるため、pgbouncer単独の因果効果を示さない表現にし、接続数制御がない点と非導入環境で再現しうる点は維持する。

Comment on lines +562 to +564
### 8.3 試験環境についての確認事項

本節の試験は 2.4 節が明示した方針(「DB は共有クラスタに向けた試験を最初から実施しない」)から外れ、共有 HA クラスタ上の専用データベースに対して実施されている。結果として巻き込み事故は発生していないが、これは「今回はたまたま問題が起きなかった」以上の保証ではない。今後の試験(issue 3・4 の Track A/B 実行時など)でも同様に共有基盤を使うか、2.4 節の方針通り隔離 DB 環境を別途整備するかは、GM・FinanSu との巻き込みリスク(同一物理ノード上での CPU・メモリ・スワップ圧迫)を踏まえて改めて MT で確認する

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

共有HAクラスタ利用を後続試験の選択肢として残さないでください。

PRの方針は隔離DBのみの利用です。今回の逸脱を記録するだけでなく、issue 3・4を「隔離DB環境の整備完了」を開始条件にし、共有クラスタを使う場合は明示的な例外承認と資源監視を必須にしてください。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/development/load-test-plan.md` around lines 562 - 564, Update section
8.3 and the issue 3・4 execution prerequisites to require a completed isolated
database environment before testing starts. Remove shared HA cluster use as a
normal option; if an exception is permitted, require explicit approval and
resource monitoring.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

API負荷試験の事前調査結果と試験計画をドキュメント化する

1 participant