LESSON 30分

ストーリー

田中VPoE
デプロイ戦略がわかったところで、次はサービングインフラの設計だ。LLMアプリケーションを安定して提供するためのインフラ構成を考えよう
あなた
今はECS上でアプリケーションを動かしていますが、LLM APIへのプロキシ部分が不安定で、タイムアウトが頻発しています
田中VPoE
LLMのAPIコールは従来のREST APIとは特性が違う。レスポンス時間が数秒〜数十秒と長く、ストリーミングレスポンスもある。それに合わせたインフラ設計が必要だ

サービングインフラの特性

LLM APIコールの特性

特性従来のREST APILLM APIコール
レスポンス時間数十ms〜数百ms数秒〜数十秒
レスポンスサイズ予測可能トークン数により大きく変動
接続方式リクエスト/レスポンスストリーミング(SSE)が一般的
タイムアウト5〜30秒30秒〜120秒
リトライ短時間で可能コスト増加のため慎重に
エラーパターンHTTPステータスコードレート制限、コンテンツフィルタ、トークン上限超過

インフラ構成パターン

基本構成

本番サービングインフラ:

┌────────────────────────────────────────────────────┐
│                    VPC                              │
│                                                    │
│  ┌──────────┐    ┌──────────────┐    ┌──────────┐ │
│  │   ALB    │ →  │  ECS Service │ →  │  Redis   │ │
│  │          │    │  (LiteLLM    │    │  (Cache) │ │
│  │ SSL終端  │    │   Proxy)     │    │          │ │
│  │ ヘルスチェック│    │              │    └──────────┘ │
│  └──────────┘    │  Min: 2      │                  │
│                  │  Max: 10     │    ┌──────────┐  │
│                  └──────┬───────┘    │ RDS      │  │
│                         │           │ (Langfuse │  │
│                         │           │  メタデータ) │  │
│                         │           └──────────┘  │
└─────────────────────────┼──────────────────────────┘

                ┌─────────┼─────────┐
                ▼         ▼         ▼
           OpenAI API  Anthropic  Self-hosted
                       API        Model

コンポーネント別設計

コンポーネント技術選択設計ポイント
ロードバランサALBWebSocket/SSE対応、長時間接続のタイムアウト設定
GatewayECS Fargate + LiteLLMステートレス設計、水平スケーリング
キャッシュElastiCache (Redis)セマンティックキャッシュ、TTL管理
メタデータDBRDS PostgreSQLログ・設定の永続化
シークレット管理AWS Secrets ManagerAPIキーのローテーション

接続管理

タイムアウト設計

LLM APIの長い応答時間に対応するため、各層のタイムアウトを適切に設定します。

タイムアウトチェーン:

クライアント (120s) → ALB (90s) → Gateway (60s) → LLM API (30s)

各層のタイムアウト:
┌──────────┐  120s  ┌──────┐  90s  ┌─────────┐  60s  ┌─────────┐
│ Client   │ ────→  │ ALB  │ ───→ │ Gateway │ ───→ │ LLM API │
└──────────┘        └──────┘      └─────────┘      └─────────┘

ポイント:
  - 外側ほど長いタイムアウトを設定(内側の処理完了+バッファ)
  - LLM APIの30sは1リクエストあたりの制限
  - ストリーミング時はfirst byte timeout と total timeoutを分離
タイムアウト説明
クライアント120秒ユーザーの最大待機時間
ALB90秒アイドルタイムアウト
Gateway60秒バックエンドへの接続タイムアウト
LLM API30秒単一リクエストのタイムアウト
ストリーミング first byte10秒最初のトークンが届くまでの制限

コネクションプーリング

# コネクションプール設計例
import httpx

# LLM APIへの接続プール
llm_client = httpx.AsyncClient(
    limits=httpx.Limits(
        max_connections=100,        # 最大同時接続数
        max_keepalive_connections=20,  # キープアライブ接続数
        keepalive_expiry=30,        # キープアライブ有効期間(秒)
    ),
    timeout=httpx.Timeout(
        connect=5.0,     # 接続タイムアウト
        read=60.0,       # 読み取りタイムアウト
        write=10.0,      # 書き込みタイムアウト
        pool=10.0,       # プール取得タイムアウト
    ),
)

ストリーミング対応

SSE(Server-Sent Events)の設計

項目設計ポイント
ALB設定HTTP/2対応を有効化、アイドルタイムアウトを延長
バッファリングプロキシバッファリングを無効化(X-Accel-Buffering: no)
再接続クライアント側でSSE再接続ロジックを実装
部分応答保存ストリーミング途中の断絶に備え、受信済みトークンを保存
ストリーミングの流れ:

Client ←── SSE ──── Gateway ←── SSE ──── LLM API
  │                    │
  │  Token 1           │  Token 1
  │  Token 2           │  Token 2
  │  Token 3           │  Token 3
  │  ...               │  ...
  │  [DONE]            │  [DONE]
  │                    │
  │                    ├── ログ記録(完全なレスポンスを構築)
  │                    └── メトリクス記録(TTFT, トークン数, レイテンシ)

ヘルスチェックとレディネス

ヘルスチェック設計

チェック種別確認内容間隔
LivenessGatewayプロセスが生存しているか10秒
ReadinessLLM APIへの接続が可能か30秒
Deep HealthRedis接続、DB接続、プロバイダ到達性60秒
ヘルスチェック階層:

/health/live     → プロセス生存確認(軽量)
/health/ready    → サービス準備完了確認
/health/deep     → 全依存関係の確認(重量)
  ├── Redis接続
  ├── DB接続
  ├── OpenAI API疎通
  └── Anthropic API疎通

障害分離設計

バルクヘッドパターン

サービスごとにリソースを分離し、1つのサービスの障害が他に波及しないようにします。

バルクヘッドパターン:

┌─────────────────────────────────────┐
│            Gateway                   │
│                                     │
│  ┌───────────┐  ┌───────────┐      │
│  │ CS-AI     │  │ FAQ Bot   │      │
│  │ Pool      │  │ Pool      │      │
│  │ (50 conn) │  │ (30 conn) │      │
│  └───────────┘  └───────────┘      │
│  ┌───────────┐                      │
│  │ CodeReview│  各プールが独立       │
│  │ Pool      │  → 1サービスの過負荷が│
│  │ (20 conn) │    他に波及しない     │
│  └───────────┘                      │
└─────────────────────────────────────┘

まとめ

ポイント内容
LLM API特性レスポンス時間が長く、ストリーミングが一般的。タイムアウトと接続管理が重要
タイムアウト外側ほど長いタイムアウトチェーンを設計し、各層で適切な制限を設ける
ストリーミングALBのHTTP/2対応、バッファリング無効化、部分応答保存が必要
障害分離バルクヘッドパターンでサービス間の影響を遮断する

チェックリスト

  • LLM APIコールの特性と従来のREST APIとの違いを理解した
  • タイムアウトチェーンの設計方法を把握した
  • ストリーミング対応の設計ポイントを理解した
  • バルクヘッドパターンによる障害分離を説明できる

推定読了時間: 30分