Performance & Scalabilityシリーズの一部
完全ガイドを読むWeb アプリケーションの負荷テスト戦略: ユーザーが実行する前にブレーク ポイントを見つける
パフォーマンスの問題の 80% は、テストではなくエンド ユーザーによって発見されます。 負荷テストでは、ユーザーが問題に遭遇する前にアプリケーションに対して現実世界のトラフィック パターンをシミュレートすることで、この比率を逆転させます。ブラック フライデーのトラフィックを処理するサイトとクラッシュするサイトの違いは、ほとんどの場合、誰かが最初に負荷テストを実行したかどうかです。
このガイドでは、Web アプリケーション、e コマース プラットフォーム、ERP システムの負荷テスト方法、ツールの選択、テスト設計、結果の解釈について説明します。
重要なポイント
- 負荷テストでは、単一のエンドポイントを攻撃するだけでなく、現実的なユーザーの動作をシミュレートする必要があります
- 最適化する前にパフォーマンスのベースラインを確立する --- 測定していないものを改善することはできません
- 運用環境に似た環境で負荷テストを実行します。ステージングの結果は本番環境の動作を反映していない可能性があります
- CI/CD での負荷テストを自動化し、展開前にパフォーマンスの低下を検出します
負荷テストの種類
| テストの種類 | 目的 | 期間 | 負荷パターン |
|---|---|---|---|
| 煙テスト | 最小限の負荷で基本機能を検証する | 1 ~ 2 分 | 1 ~ 5 ユーザー |
| 負荷テスト | 予想されるトラフィックの下でパフォーマンスを検証する | 10~30分 | 通常の交通 |
| ストレステスト | 限界点を見つける | 15~30分 | 徐々に増加 |
| スパイクテスト | 突然のトラフィックの急増をテストする | 5~10分 | 突然のジャンプ |
| 浸漬試験 | メモリ リークとメモリ劣化を検出する | 2~8時間 | 持続通常負荷 |
k6 による負荷テスト
基本的な負荷テスト
// k6/load-test.js
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
stages: [
{ duration: '2m', target: 50 }, // Ramp up to 50 users
{ duration: '5m', target: 50 }, // Stay at 50 users
{ duration: '2m', target: 100 }, // Ramp up to 100 users
{ duration: '5m', target: 100 }, // Stay at 100 users
{ duration: '2m', target: 0 }, // Ramp down
],
thresholds: {
http_req_duration: ['p(95)<500', 'p(99)<1000'],
http_req_failed: ['rate<0.01'],
http_reqs: ['rate>100'],
},
};
export default function () {
// Simulate realistic user behavior
const homeResponse = http.get('https://example.com/');
check(homeResponse, {
'homepage status is 200': (r) => r.status === 200,
'homepage loads in under 1s': (r) => r.timings.duration < 1000,
});
sleep(Math.random() * 3 + 1); // 1-4 seconds think time
const productsResponse = http.get('https://example.com/api/v1/products');
check(productsResponse, {
'products API is 200': (r) => r.status === 200,
'products API under 500ms': (r) => r.timings.duration < 500,
});
sleep(Math.random() * 2 + 1);
}
eコマース ユーザー ジャーニー テスト
// k6/ecommerce-journey.js
import http from 'k6/http';
import { check, group, sleep } from 'k6';
export const options = {
scenarios: {
browsing: {
executor: 'ramping-vus',
startVUs: 0,
stages: [
{ duration: '5m', target: 200 },
{ duration: '10m', target: 200 },
{ duration: '5m', target: 0 },
],
exec: 'browsingScenario',
},
purchasing: {
executor: 'ramping-vus',
startVUs: 0,
stages: [
{ duration: '5m', target: 20 },
{ duration: '10m', target: 20 },
{ duration: '5m', target: 0 },
],
exec: 'purchaseScenario',
},
},
thresholds: {
'http_req_duration{scenario:browsing}': ['p(95)<800'],
'http_req_duration{scenario:purchasing}': ['p(95)<2000'],
http_req_failed: ['rate<0.01'],
},
};
export function browsingScenario() {
group('Browse Products', () => {
http.get('https://store.example.com/');
sleep(2);
http.get('https://store.example.com/products');
sleep(3);
http.get('https://store.example.com/products/sample-product');
sleep(2);
});
}
export function purchaseScenario() {
group('Purchase Flow', () => {
// Browse
http.get('https://store.example.com/products/sample-product');
sleep(1);
// Add to cart
http.post('https://store.example.com/api/cart', JSON.stringify({
productId: 'prod_123',
quantity: 1,
}), { headers: { 'Content-Type': 'application/json' } });
sleep(2);
// Checkout
http.get('https://store.example.com/cart');
sleep(3);
// Place order (simulated)
const orderResponse = http.post('https://store.example.com/api/checkout/validate', JSON.stringify({
email: `test-${__VU}@example.com`,
}), { headers: { 'Content-Type': 'application/json' } });
check(orderResponse, {
'checkout validates': (r) => r.status === 200 || r.status === 201,
});
sleep(1);
});
}
ストレス テスト (限界点を見つける)
// k6/stress-test.js
import http from 'k6/http';
import { check } from 'k6';
export const options = {
stages: [
{ duration: '2m', target: 100 },
{ duration: '5m', target: 100 },
{ duration: '2m', target: 200 },
{ duration: '5m', target: 200 },
{ duration: '2m', target: 500 },
{ duration: '5m', target: 500 },
{ duration: '2m', target: 1000 },
{ duration: '5m', target: 1000 },
{ duration: '5m', target: 0 },
],
};
export default function () {
const res = http.get('https://example.com/api/v1/products');
check(res, {
'status is 200': (r) => r.status === 200,
});
}
結果の解釈
主要な指標
| メトリック | 健康 | 警告 | クリティカル |
|---|---|---|---|
| P95 応答時間 | <500ms | 500ms-2s | >2秒 |
| P99 応答時間 | <1秒 | 1-5秒 | >5秒 |
| エラー率 | <0.1% | 0.1-1% | >1% |
| スループット | 目標を達成 | 目標の 80% | 目標の 80% 未満 |
一般的なボトルネック パターン
CPU バウンドのボトルネック: 応答時間は負荷に応じて直線的に増加します。 P95 と P99 はゆっくりと発散します。
- 修正: ホット コード パスの最適化、CPU 容量の追加、または水平方向のスケーリング
データベースのボトルネック: 応答時間は、特定の負荷しきい値で指数関数的に増加します。接続プールが枯渇しました。
- 修正: クエリの最適化、接続プーリング、リードレプリカ (データベース スケーリング ガイド を参照)
メモリのボトルネック: 時間の経過とともに徐々に劣化します。 GC の一時停止により、レイテンシのスパイクが発生します。
- 修正: メモリを増やし、メモリ リークを修正し、オブジェクト割り当てを最適化します。
ネットワークのボトルネック: 応答時間はすべてのエンドポイントで均一に増加します。帯域幅の飽和。
- 修正: 静的アセットの CDN、圧縮、ペイロード サイズの削減
パフォーマンスのベースライン
ベースラインの確立
最適化する前に、現在のパフォーマンスを文書化します。
# Run baseline test
k6 run --out json=baseline-results.json k6/load-test.js
# Compare after optimization
k6 run --out json=optimized-results.json k6/load-test.js
パフォーマンス予算
各エンドポイントの許容可能なパフォーマンスを定義します。
| エンドポイント | P95 ターゲット | スループット目標 |
|---|---|---|
| ホームページ | 500ミリ秒 | 200 リクエスト/秒 |
| 製品一覧 | 800ミリ秒 | 150 リクエスト/秒 |
| 製品詳細 | 600ミリ秒 | 200 リクエスト/秒 |
| カートに追加 | 300ミリ秒 | 100 リクエスト/秒 |
| チェックアウト | 2000ミリ秒 | 50 リクエスト/秒 |
| 検索 | 500ミリ秒 | 100 リクエスト/秒 |
| 管理者ダッシュボード | 1500ミリ秒 | 20 リクエスト/秒 |
CI/CD の統合
自動パフォーマンス回帰テスト
# .github/workflows/performance.yml
name: Performance Test
on:
push:
branches: [main]
jobs:
load-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run k6 load test
uses: grafana/[email protected]
with:
filename: k6/load-test.js
flags: --out json=results.json
env:
K6_TARGET_URL: ${{ secrets.STAGING_URL }}
- name: Check thresholds
run: |
if grep -q '"thresholds":{".*":"fail"' results.json; then
echo "Performance thresholds exceeded!"
exit 1
fi
負荷テストのチェックリスト
テストの前に
- 環境は本番環境と一致します (インスタンス タイプ、データベース サイズ)。
- テスト データは代表的なものです (現実的な製品数、ユーザー数)。
- モニタリングがアクティブです (テスト中にサーバーのメトリクスを追跡します)
- 関係者に通知されます (負荷テストによりアラートがトリガーされる可能性があります)
- CDN とキャッシュは運用環境と同じように構成されています
テスト中
- サーバーの CPU、メモリ、ディスク I/O を監視します
- データベース接続とクエリ遅延を監視します。
- エラー率の増加に注意してください
- リソースの枯渇をチェックします (ファイル記述子、接続)
- パフォーマンスが低下する負荷レベルに注意してください
テスト後
- ベースライン結果を文書化する
- ボトルネックとその負荷しきい値を特定します
- パフォーマンス向上のためのチケットを作成する
- パフォーマンス バジェットと比較する
- 最適化後のフォローアップ テストをスケジュールする
よくある質問
テストの本番環境またはステージングをロードする必要がありますか?
できれば両方。定期的なテストと CI/CD 統合のためのステージング。ステージングではデータベース サイズ、キャッシュ ウォーム、CDN 構成、およびネットワーク トポロジが異なることが多いため、定期的な検証 (トラフィックの少ない時間帯) のための運用。 1 つの環境しかテストできない場合は、ステージングをテストしますが、できる限り実稼働環境に近づけてください。
負荷テストはどれくらいの頻度で実行する必要がありますか?
すべてのデプロイメントでスモーク テストを実行します (CI/CD で自動化)。全負荷テストは毎週、またはメジャー リリース前に行われます。ストレス テストは四半期ごと、または既知のトラフィックの多いイベント (販売、発売) の前に実施します。ソーク テストを四半期ごとに実施して、メモリ リークと長期的な劣化を検出します。
ERP システムの負荷テストはどのように行うのでしょうか?
ERP 負荷テストでは、請求書の生成、注文書の作成、レポートの実行、データのインポートなど、さまざまなタスクを実行する同時ユーザーをシミュレートする必要があります。最も負荷の高い操作 (レポート生成、データ インポート) と最も同時実行される操作 (ピーク時の注文入力) に焦点を当てます。 ECOSIRE は、サポート サービスの一環として Odoo パフォーマンス テスト を提供します。
リクエスト間の現実的な思考時間はどれくらいですか?
e コマースのブラウジングの場合: 2 ~ 5 秒。フォーム入力の場合: 10 ~ 30 秒。チェックアウトの場合: 15 ~ 60 秒。管理者/ERP 使用の場合: 5 ~ 15 秒。負荷テストには常にランダム化された思考時間を追加してください。一定の間隔では、非現実的な同期負荷パターンが作成されます。
次に何が起こるか
負荷テストにより、最適化の取り組みの指針となるボトルネックが明らかになります。データベースのボトルネックについては データベース スケーリング、静的アセット配信については CDN 最適化、エラスティック キャパシティについては 自動スケーリング をフォローアップします。
パフォーマンスのテストと最適化については ECOSIRE にお問い合わせ、完全なインフラストラクチャ戦略については DevOps ガイド をご覧ください。
ECOSIRE が発行 -- 企業がプレッシャーの下でもパフォーマンスを発揮するアプリケーションを構築できるように支援します。
執筆者
ECOSIRE Research and Development Team
ECOSIREでエンタープライズグレードのデジタル製品を開発。Odoo統合、eコマース自動化、AI搭載ビジネスソリューションに関するインサイトを共有しています。
関連記事
AI エージェントのパフォーマンスの最適化: 速度、精度、コスト効率
迅速なエンジニアリング、キャッシュ、モデル選択、監視のための実証済みの技術により、応答時間、精度、コスト全体にわたって AI エージェントのパフォーマンスを最適化します。
最新のアプリケーションの API ゲートウェイ パターンとベスト プラクティス
スケーラブルな Web アーキテクチャ向けに、レート制限、認証、リクエスト ルーティング、サーキット ブレーカー、API バージョン管理などの API ゲートウェイ パターンを実装します。
CDN パフォーマンスの最適化: グローバル配信を高速化するための完全ガイド
キャッシュ戦略、エッジ コンピューティング、画像の最適化、マルチ CDN アーキテクチャにより CDN パフォーマンスを最適化し、グローバル コンテンツ配信を高速化します。
Performance & Scalabilityのその他の記事
AI エージェントのパフォーマンスの最適化: 速度、精度、コスト効率
迅速なエンジニアリング、キャッシュ、モデル選択、監視のための実証済みの技術により、応答時間、精度、コスト全体にわたって AI エージェントのパフォーマンスを最適化します。
AI エージェントのテストと監視: 自律システムの信頼性エンジニアリング
AI エージェントのテストと監視に関する完全なガイド。単体テスト、統合テスト、動作テスト、可観測性、運用監視戦略をカバーします。
CDN パフォーマンスの最適化: グローバル配信を高速化するための完全ガイド
キャッシュ戦略、エッジ コンピューティング、画像の最適化、マルチ CDN アーキテクチャにより CDN パフォーマンスを最適化し、グローバル コンテンツ配信を高速化します。
e コマース向けモバイル SEO: 2026 年の完全な最適化ガイド
eコマースサイト向けのモバイルSEOガイド。モバイル ファースト インデックス、Core Web Vitals、構造化データ、ページ速度の最適化、モバイル検索のランキング要素をカバーします。
本番環境の監視とアラート: 完全なセットアップ ガイド
Prometheus、Grafana、Sentry を使用して、本番環境の監視とアラートを設定します。メトリクス、ログ、トレース、アラート ポリシー、インシデント対応ワークフローをカバーします。
API パフォーマンス: レート制限、ページネーション、非同期処理
レート制限アルゴリズム、カーソルベースのページネーション、非同期ジョブ キュー、応答圧縮のベスト プラクティスを使用して、高パフォーマンスの API を構築します。