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 したイベントが即座にブラウザへ届かず、数秒〜数分間イベントが届かないフリーズ状態が発生し、バッファが溢れた瞬間に一括大量届く通信壊滅障害 が発生します。
解消手順
- サーバー/ロードバランサー(Nginx, Cloudflare, ALB等)で ALPN ネゴシエーションを有効化し HTTP/2 接続にする
- Nginx の SSE 配信パスの
locationブロックにproxy_buffering off;およびproxy_cache off;を記述する - バックエンドのレスポンスヘッダーに
Content-Type: text/event-streamとCache-Control: no-cacheを出力させる