テスト概要
| 項目 | 詳細 |
|---|
| テスト日 | 2025年12月14日 |
| 対象エンドポイント | POST /token (grant_type=token-exchange) |
| 目的 | マイクロサービス認証およびSSOオーディエンス切り替えのパフォーマンスを測定 |
テスト環境
K6 Cloud構成
インフラ
| コンポーネント | テクノロジー |
|---|
| コンピュート | Cloudflare Workers (op-token) |
| 失効チェック | Durable Objects (TokenRevocationStore) |
| 鍵管理 | Durable Objects (KeyManager) |
| データベース | Cloudflare D1 |
シャード構成
| Durable Object | シャード数 | 用途 |
|---|
| AuthorizationCodeStore | 8 | 認可コード管理 |
| SessionStore | 8 | セッション管理 |
| ChallengeStore | 8 | チャレンジ管理 |
| TokenRevocationStore | 8 | トークン失効チェック(メインDO) |
| RefreshTokenRotator | 16 | リフレッシュトークン管理 |
テスト方法論
トークンミックス(RFC 8693 + 業界標準)
| トークンタイプ | 比率 | 期待結果 | 検証項目 |
|---|
| 有効(標準) | 56% | 新トークン発行 | Scope/sub整合性 |
| 有効(actor付き) | 14% | 新トークン発行 | 委譲フロー (RFC 8693) |
| 期限切れ | 10% | 400エラー | 即時検出 |
| 無効署名 | 10% | 400エラー | 署名検証 |
| 失効済み | 10% | 400エラー | リアルタイム失効チェック |
トークン交換バリエーション
| バリエーション | 種類数 | 例 |
|---|
| Target Audience | 20 | api.example.com/gateway, /users, /payments, … |
| Scope Patterns | 4 | openid, openid profile, openid profile email, full |
| Resource URI | 10 | resource.example.com/api/v1, data.example.com/graphql, … |
| Service Clients | 5 | service-gateway, service-bff, service-worker, … |
結果 - パフォーマンスメトリクス
サマリー
| RPS | 総リクエスト数 | K6 P95 | CF Worker P99 | CF DO P99 | 状態 |
|---|
| 2,000 | 292,343 | 500ms | 307ms | 1,020ms | ⚠️ |
| 2,500 | 365,624 | 225ms | 313ms | 271ms | ✅ |
| 3,000 | 390,444 | 2,144ms | 316ms | 2,222ms | ❌ |
判定基準: ✅ K6 P95 < 300ms AND DO P99 < 500ms
K6クライアントレイテンシ(ms)
| RPS | Median | P95 | P99 | Min | Max |
|---|
| 2,000 | 112 | 500 | 589 | 40 | 3,448 |
| 2,500 | 76 | 225 | 297 | 39 | 5,075 |
| 3,000 | 1,657 | 2,144 | 2,269 | 53 | 4,236 |
RPS達成率
| 目標RPS | 平均RPS | ピークRPS | 達成率 |
|---|
| 2,000 | 1,373 | 2,137 | 107% |
| 2,500 | 1,717 | 2,494 | 100% |
| 3,000 | 1,833 | 2,714 | 90% |
注: 3,000 RPSテストで”Insufficient VUs”警告発生
結果 - インフラメトリクス
Worker Duration (ms)
| RPS | 総リクエスト | P50 | P75 | P90 | P99 | P999 |
|---|
| 2,000 | 293,747 | 23.83 | 26.04 | 60.67 | 306.87 | 309.91 |
| 2,500 | 367,484 | 23.09 | 24.52 | 26.43 | 312.86 | 315.63 |
| 3,000 | 398,732 | 204.33 | 236.41 | 265.56 | 315.89 | 337.54 |
Worker CPU Time (ms)
| RPS | P50 | P75 | P90 | P99 | P999 |
|---|
| 2,000 | 2.27 | 3.06 | 3.64 | 8.47 | 16.59 |
| 2,500 | 2.23 | 2.52 | 3.19 | 8.44 | 15.89 |
| 3,000 | 2.13 | 2.37 | 3.03 | 4.97 | 7.23 |
重要な発見: CPU時間はP50で約2.3msで安定 - CPUはボトルネックではない
Durable Objects Wall Time (ms)
TokenRevocationStore + KeyManager DO:
| RPS | 総DOリクエスト | DOエラー | P50 | P75 | P90 | P99 | P999 |
|---|
| 2,000 | 620,073 | 0 | 17.76 | 29.88 | 102.05 | 1,019.69 | 1,312.22 |
| 2,500 | 764,279 | 0 | 15.08 | 28.63 | 46.66 | 271.45 | 378.61 |
| 3,000 | 759,010 | 8 | 759.34 | 1,512.10 | 1,821.78 | 2,222.33 | 2,450.69 |
重要な発見:
- 2,500 RPSがスイートスポット(P99 271ms)
- 3,000 RPSでDOが飽和(P50が759msに急上昇)
- 3,000 RPSでDOエラー発生開始
DO呼び出し並列化の効果
実装
const publicKey = await getVerificationKeyFromJWKS(env, kid);
const revoked = await isTokenRevoked(env, jti);
const [publicKey, revoked] = await Promise.all([
getVerificationKeyFromJWKS(env, kid),
3,000 RPSでの影響
| メトリクス | Before | After | 変化 |
|---|
| DO P50 | 49ms | 28ms | -43% |
| DO P99 | 2,141ms | 2,222ms | ±同等 |
| Worker P99 | 307ms | 316ms | ±同等 |
P50が大幅改善。P99は高負荷時のキューイングが支配的なため変化なし。
キャパシティ推奨
| 用途 | 推奨RPS | 根拠 |
|---|
| 通常運用 | ≤1,500 | 余裕のある安定動作 |
| ピーク対応 | ≤2,500 | K6 P95 225ms、DO P99 271ms - 最適点 |
| 絶対上限 | ≤2,700 | ピークRPS達成可能な上限 |
主要な発見
1. CPU処理は高速で安定
CPU Time P50は全RPS帯で2.1-2.3ms - CPUはボトルネックではありません。
2. DOがボトルネック
3,000 RPSでDO P50が15ms→759msに急上昇(50倍悪化)。
3. 2,500 RPSがスイートスポット
最良のパフォーマンスは2,500 RPSで達成:
- K6 P95: 225ms
- DO P99: 271ms
4. 3,000 RPSでシステムが飽和
- DOキューイング遅延が支配的
- パフォーマンスが急激に劣化
- DOエラー発生開始(8件)
5. 100%トークン検証精度
全トークンタイプが正確に検証:
- 有効 → 新トークン発行
- 期限切れ → 400エラー
- 無効署名 → 400エラー
- 失効済み → 400エラー(リアルタイムチェック)
結論
AuthrimのToken Exchange(RFC 8693)エンドポイントは:
- 2,500 RPSまで: 安定動作(K6 P95 225ms、CF DO P99 271ms)
- 3,000 RPS以上: 顕著な劣化(K6 P95 > 2,100ms、CF DO P50 > 750ms)
主要ボトルネックはDurable Objectのキューイング遅延 - CPUや暗号操作ではありません。さらなるスケールアウトにはDO最適化またはアーキテクチャ変更(キャッシュレイヤー追加など)が必要です。
全RPS帯で100%成功率を達成 - スループット限界でもトークン検証の正確性は維持されています。