ストーリー
高橋アーキテクトが続けた。
シナリオ設計の3ステップ
Step 1: ユーザー行動の分析
実際のトラフィックパターンをアクセスログから分析します。
// アクセスログから行動パターンを抽出
interface UserBehaviorPattern {
name: string;
percentage: number; // 全トラフィックに占める割合
actions: Action[];
}
const patterns: UserBehaviorPattern[] = [
{
name: '閲覧のみユーザー',
percentage: 60, // 60%のユーザー
actions: [
{ endpoint: 'GET /products', weight: 50 },
{ endpoint: 'GET /products/:id', weight: 30 },
{ endpoint: 'GET /categories', weight: 20 },
],
},
{
name: '検索ユーザー',
percentage: 25,
actions: [
{ endpoint: 'GET /search?q=...', weight: 40 },
{ endpoint: 'GET /products/:id', weight: 40 },
{ endpoint: 'POST /cart', weight: 20 },
],
},
{
name: '購入ユーザー',
percentage: 15,
actions: [
{ endpoint: 'GET /products/:id', weight: 20 },
{ endpoint: 'POST /cart', weight: 20 },
{ endpoint: 'GET /cart', weight: 20 },
{ endpoint: 'POST /orders', weight: 20 },
{ endpoint: 'GET /orders/:id', weight: 20 },
],
},
];
Step 2: ワークロードモデルの定義
// ワークロードモデル
interface WorkloadModel {
// 目標負荷
targetRPS: number;
targetVUs: number; // Virtual Users
// エンドポイント別の負荷配分
endpoints: EndpointLoad[];
// 思考時間(ユーザーがページを見ている時間)
thinkTime: {
min: number; // 最小(秒)
max: number; // 最大(秒)
avg: number; // 平均(秒)
};
}
const workload: WorkloadModel = {
targetRPS: 3000,
targetVUs: 500,
endpoints: [
{ path: 'GET /products', rpsShare: 30 }, // 900 RPS
{ path: 'GET /products/:id', rpsShare: 25 }, // 750 RPS
{ path: 'GET /search', rpsShare: 15 }, // 450 RPS
{ path: 'GET /categories', rpsShare: 10 }, // 300 RPS
{ path: 'POST /cart', rpsShare: 8 }, // 240 RPS
{ path: 'GET /cart', rpsShare: 5 }, // 150 RPS
{ path: 'POST /orders', rpsShare: 4 }, // 120 RPS
{ path: 'GET /orders/:id', rpsShare: 3 }, // 90 RPS
],
thinkTime: { min: 1, max: 10, avg: 3 },
};
Step 3: テストデータの準備
// テストデータの設計
interface TestDataRequirements {
// ユーザーデータ
users: {
count: number; // 必要なテストユーザー数
distribution: string; // 均等 or 偏りあり
};
// 商品データ
products: {
count: number;
popularProducts: number; // 人気商品(アクセス集中)
accessPattern: string; // べき乗分布(一部に集中)
};
// 検索クエリ
searchQueries: {
count: number;
source: string; // 実際のアクセスログから抽出
};
}
const testData: TestDataRequirements = {
users: {
count: 10000,
distribution: 'unique per VU',
},
products: {
count: 5000,
popularProducts: 100, // 上位100商品にアクセスの80%が集中
accessPattern: 'zipf', // べき乗分布
},
searchQueries: {
count: 500,
source: 'production access log (anonymized)',
},
};
テストの成功基準(SLO)
// Service Level Objectives
interface TestSLO {
// レイテンシ
latency: {
p50: number; // 100ms
p95: number; // 300ms
p99: number; // 500ms
};
// スループット
throughput: {
minRPS: number; // 最低3000 RPS
};
// エラー率
errorRate: {
max: number; // 0.1%以下
};
// リソース使用率
resources: {
maxCPU: number; // 80%以下
maxMemory: number; // 80%以下
};
}
const slo: TestSLO = {
latency: { p50: 100, p95: 300, p99: 500 },
throughput: { minRPS: 3000 },
errorRate: { max: 0.1 },
resources: { maxCPU: 80, maxMemory: 80 },
};
シナリオ設計のチェックリスト
- 現実的か — 実際のユーザー行動を反映しているか
- 再現可能か — 同じ条件で何度でも実行できるか
- 測定可能か — 明確な成功基準が定義されているか
- テストデータは十分か — キャッシュヒットが100%にならないか
- 思考時間を含むか — 実ユーザーの待ち時間を模倣しているか
まとめ
| ポイント | 内容 |
|---|---|
| ユーザー行動分析 | アクセスログから実際のパターンを抽出 |
| ワークロードモデル | エンドポイント別の負荷配分を定義 |
| テストデータ | べき乗分布で現実的なアクセスパターン |
| SLO | レイテンシ、スループット、エラー率の成功基準 |
チェックリスト
- ユーザー行動パターンの分析方法を理解した
- ワークロードモデルの定義方法を把握した
- テストデータの設計ポイントを理解した
- テストの成功基準(SLO)を定義できる
次のステップへ
次は「k6による負荷テスト」を学びます。設計したシナリオを実際にコードとして実装しましょう。
推定読了時間: 30分