WebSocket接続のスケーリング:学んだ教訓
1万以上の同時接続を処理するためのWebSocketインフラストラクチャスケーリングからの実践的な知見
WebSocket Scaling Redis Architecture
課題
XRプラットフォームが成長し始めたとき、約5,000同時接続で典型的なWebSocketスケーリングの壁にぶつかりました。それをどう解決したかをご紹介します。
問題1: 接続制限
各サーバーインスタンスにはファイルディスクリプタの制限があります。インスタンスあたり約4,000接続でこの問題に直面しました。
解決策: ulimit設定を増やし、ロードバランサーによる水平スケーリングを実装しました。
# /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535
問題2: スティッキーセッション
WebSocket接続は同じサーバーに留まる必要がありますが、従来の負荷分散ではこれが考慮されていません。
解決策: ロードバランサーでのIPハッシュベースルーティング:
upstream websocket_servers {
ip_hash;
server ws1.example.com:8080;
server ws2.example.com:8080;
server ws3.example.com:8080;
}
問題3: サーバー間通信
異なるサーバー上のユーザーが互いに通信する必要がありました。
解決策: メッセージブロードキャスト用のRedis Pub/Sub:
// 全サーバーにメッセージを公開
await redis.PublishAsync("room:123", message);
// 各サーバーがサブスクライブしてローカルクライアントに転送
subscriber.Subscribe("room:*", (channel, message) => {
BroadcastToLocalClients(channel, message);
});
結果
これらのソリューションを実装した後:
- 5Kから15K同時接続にスケールアップ
- 6ヶ月間で99.9%の稼働率
- 平均レイテンシを150msから45msに削減
重要なポイント
- 最初から水平スケーリングを計画する
- サーバー間メッセージングにRedis Pub/Subを使用する
- 接続数とメモリ使用量を綿密に監視する