Server-Sent Events (SSE) で発生する HTTP/1.1 6接続制限の回避策

HTTP Performance Frontend Backend
結論

通信フリーズを防ぐため HTTP/2 の導入と Nginx での proxy_buffering off; を設定します。

# MDN / Nginx公式仕様:SSE 用プロキシバッファリング無効化設定
server {
    listen 443 ssl http2; # HTTP/2 有効化によりブラウザ6接続制限を完全解除
    server_name example.com;

    location /api/sse {
        proxy_pass http://backend_server;
        
        # ⭕ バッファリングを完全に切る(リアルタイム配信に必須)
        proxy_buffering off;
        proxy_cache off;
        
        # 接続の持続化
        proxy_set_header Connection '';
        proxy_http_version 1.1;
        chunked_transfer_encoding off;
    }
}

MDN公式仕様:HTTP/1.1 と HTTP/2 の接続制限比較

MDN公式ドキュメント(EventSource)で説明されている通り、SSE(Server-Sent Events)は持続的な HTTP 接続(Long-lived Connection)を維持してサーバーからリアルタイムイベントを受信します。

項目HTTP/1.1 通信HTTP/2 / HTTP/3 通信
同一ドメイン接続制限最大 6 接続まで(ブラウザ仕様)実質無制限(最大100ストリーム多重化)
複数タブ起動時の影響7タブ目で全通信が Pending フリーズ1つのTCP接続に集約されスムーズに動作
ヘッダー圧縮なし(毎回プレーンテキスト送出)HPACK による高速圧縮ヘッダー

実際に起こる障害:Nginx proxy_buffering によるリアルタイム通信崩壊事故

SSEの環境構築で最も多発するトラブルが、リバースプロキシ(Nginx 等)によるレスポンスの遅延バッファリング事故 です。

Nginx はデフォルトで proxy_buffering ON が有効になっています。プロキシがレスポンスデータを一定サイズ(4KB〜8KB)まで溜め込んでからまとめてクライアントへ送ろうとするため、サーバーが yield したイベントが即座にブラウザへ届かず、数秒〜数分間イベントが届かないフリーズ状態が発生し、バッファが溢れた瞬間に一括大量届く通信壊滅障害 が発生します。


解消手順

  1. サーバー/ロードバランサー(Nginx, Cloudflare, ALB等)で ALPN ネゴシエーションを有効化し HTTP/2 接続にする
  2. Nginx の SSE 配信パスの location ブロックに proxy_buffering off; および proxy_cache off; を記述する
  3. バックエンドのレスポンスヘッダーに Content-Type: text/event-streamCache-Control: no-cache を出力させる