【WebSocket通信の実運用スケール性能ベンチマーク】

はじめに(CPU割当なしでの測定について)


WebSocket 実装と実運用に近い測定構成

本ページで紹介するベンチマーク結果は、SOCKET-MANAGER Framework の基盤上に WebSocket プロトコルを ステートマシン を使ってビジネスロジック実装した実運用に近い構成 で測定したものです。
単なる「フレームワーク単体の速度測定」ではなく、 プロトコル処理・ UNIT/Queue の状態遷移 ・イベントループ を含む フレームワーク全体の実行パスを通した純粋性能です。

長時間耐久テストでは、WebSocket(MDN WebSocket API)を用いた 10,000 / 50,000 / 100,000 接続を維持しながら実施した CPU 割当なしで実運用に近い 6 時間耐久ベンチマーク の結果をまとめています。

FFI・Sockets を用いた IO と CPU 割当なしの動作

内部処理では PHP の FFISockets 拡張 を活用した IO ドライバが動作しており、CPU 割当なしでも安定した処理が可能です。

Union によるゼロコピー設計と軽量コンテキスト管理

SOCKET-MANAGER Framework の共有基盤(Union)メモリコピーを極力発生させないゼロコピー設計 を採用しており、 セッションコンテキストやフレームデータを 不要なコピーなしで各処理系(UNIT / Queue / EventLoop)へ受け渡せます。 このゼロコピー設計により、10万同時接続規模でも GC 負荷を抑えつつ、 実測でも確認された サブミリ秒帯の安定レイテンシ を維持できる構造になっています。

ラウンド間隔なしの連続バーストと高負荷テスト

5万・10万接続の ping/pong テストでは ラウンド間隔なし で数万ラウンド規模の連続バーストを実施しており、実際のサービス運用よりも厳しい条件での動作確認となっています。

エラーなし・128MB メモリでの長時間安定性

すべての測定において エラーは発生せず、PHP のメモリ設定は標準の 128MB のままです。
つまりこのページは、「実運用に近い条件で壊れないか」を検証することに主眼を置いた結果です。


>> ベンチマーク結果を見る

FFI の独自 IO ドライバによるネイティブ級の性能を実現する機能については「ハイパフォーマンスモード」で詳しく解説しています。

▶ ハイパフォーマンスモードを見る

WebSocket と TCP のスケール特性を比較したい場合は、以下のページも参照してください。

▶ 純粋 TCP スケール性能を見る


テスト条件

共通条件

  • CPU割当:なし(プロセス・スレッドの CPU ピニングなし)
  • メモリ設定:PHP 標準の 128MB
  • 接続数:10,000 / 50,000 / 100,000
  • フレーム:ping/pong、ペイロード 100バイト
  • OS:Linux(WSL2) / Windows
  • テスト時間:6 時間(接続維持)

ラウンド条件

  • 10,000 接続時 ping/pong:ラウンド間隔 10秒
  • 50,000 / 100,000 接続時 ping/pong:ラウンド間隔なし(完了後すぐ次ラウンド)
  • 1ラウンドあたりの同時処理件数:常に 10,000
※「アクセス集中時」は、全接続から一斉にリクエストが集中する最悪条件を想定したテストです。

結果サマリー(性能・堅牢性・軽量性)

性能(Performance)

  • 10万同時接続時の ping/pong 平均レイテンシ:0.553ms(Linux)
  • 5万同時接続時の ping/pong 平均レイテンシ:0.348ms(Linux)
  • ラウンド間隔なしで 1ラウンド 10,000 件を約 5〜6 秒で連続処理

堅牢性(Robustness)

  • 全テストで エラー発生ゼロ
  • ラウンド間隔なしの連続バーストでも破綻なし
  • 10,000 → 100,000 接続でレイテンシは約 4.6 倍に収まり、スケールは線形に近い

軽量性(Lightweight)

  • 全テストを通じて PHP のメモリ設定は 128MB のまま
  • 接続数増加や長時間運用によるメモリ膨張なし

ハイパフォーマンスモードは、独自 IO ドライバと同期ランタイムの特性を組み合わせることで、 WebSocket 接続において 最大 100,000 同時接続をバースト状態の高負荷状態でも 0.55ms(サブミリ秒帯)で処理 する性能を実現しました。 Windows 環境でも 50,000 同時接続を 0.50ms(サブミリ秒帯)で処理 しており、OS を問わず安定したスケール特性を示します。

この結果は、単なるピーク値ではなく、大量同時接続のバースト状態を維持しながら 6 時間耐久テストをクリアした処理能力 を示すものです。
高負荷下でもレイテンシが安定しており、接続数が増えても エラーなし で処理時間が接続数に対して 線形にスケールする ことが確認されています。


スケール特性が証明した強み

今回の 10,000 / 50,000 / 100,000 接続の耐久ベンチマークにより、 SOCKET-MANAGER Framework のアーキテクチャが持つ以下の特徴が、 実運用スケールでも破綻しないことが明確になりました。

1. ステートマシン I/F による「状態破壊のないスケール」

フレームワーク本体にビルトインされた UNIT / Queue モデルは、 非同期処理中でも状態破壊が起きない構造を持っています。

UNIT / Queue モデルの詳細は >> イベントハンドラについて にて解説しています。

10万同時接続・連続バーストという厳しい条件下でも破綻しなかったのは、 このステートマシン構造が正しく機能している証拠です。

ステートマシンの詳細は >> イベント駆動アーキテクチャ を参照してください。

2. 統一 I/F による IPC / マイクロサービス親和性

SOCKET-MANAGER は TCP / UDP / WebSocket / IPC などを 同じステートマシン I/F で扱えるため、 プロセス単位でのスケールアウトが極めて容易です。
実際、今回のベンチマークでもプロセス構成を変えるだけで スケール戦略を柔軟に組み替えられることが確認できました。

IPC の詳細は >> IPC(プロセス間通信) にて解説しています。

3. プロセス単位で自由に組み替えられるスケール戦略

CUEI アーキテクチャの I(IPC)を中心に、 C(Communication)・U(Union)・E(Event)が統合されているため、 サーバー構成をプロセス単位で自由に組み替えることができます。
これはマイクロサービス構成との親和性を高め、 実運用でのスケール戦略を大幅に柔軟にします。

マルチサーバー構成の詳細は >> マルチサーバーの構成 を参照してください。

4. ランチャーによる論理 CPU 割当でスケール戦略を最適化

GUI / CLI ランチャーでは、サービス単位で 任意の論理 CPU を割り当てることができます。
これにより、プロセス単位のスケール戦略と CPU リソース戦略を 一体化して最適化でき、より高いスケーラビリティを実現できます。

CPU 割当の詳細は >> ランチャーのサービス設定 を参照してください。

今回のベンチマークは、 SOCKET-MANAGER Framework が「スケールしやすい構造」を持つだけでなく、 実運用レベルでもその構造が正しく機能することを証明する結果となりました。

ベンチマーク結果


純粋性能

以下の表は単接続での ping/pong フレーム(ペイロード部 100 byte の送受信)を 10,000 回繰り返した状況での測定結果です。
純粋性能(単接続 N=10,000 の ping/pong レイテンシ)
OS avg mid min max p90 p95
Linux 0.0249ms 0.0215ms 0.0203ms 3.0309ms 0.0237ms 0.0274ms
Windows 0.0618ms 0.0415ms 0.0387ms 16.0933ms 0.0438ms 0.0462ms

実運用に近い条件でのスケール特性

CPU割当なしの状態では、OS スケジューラ(参考:Linux Scheduler Documentation)の揺れや IRQ の偏りなど、実運用で発生しうるノイズの影響を受けやすくなります。

Linux 環境では、カーネルの TCP/IP スタック (参考:Linux TCP/IP stack) やイベント通知機構である epoll (参考:epoll) の挙動もレイテンシに影響するため、 高負荷時の安定性はフレームワークの設計品質を測る重要な指標となります。

そのような条件下でも、SOCKET-MANAGER Framework は 10,000 → 50,000 → 100,000 接続の増加に対して線形に近いスケール特性 を示し、高負荷時でも破綻しない堅牢性を確認できました。

SOCKET-MANAGER Framework では、OS レベルのスケジューラや TCP/IP スタックの挙動に加えて、 共有基盤(Union)においても ゼロコピーを前提としたコンテキスト管理 を行っています。 フレームデータやセッション情報をコピーせずに各処理系へ受け渡すため、 GC の影響が増幅しにくく、 高負荷時でもレイテンシが滑らかに増加する安定したスケール特性 を示します。

また、ペイロード 100 バイトの ping/pong フレーム(参考: RFC 6455) を用いた連続バーストにおいても、 10万同時接続時で平均 0.55ms 程度 に収まっており、 18,000〜20,000 rps 相当の実効スループット(10,000 接続あたり 1,800〜2,000 rps)を安定して処理できており、10万同時接続でも破綻しない堅牢性を示しています。


グラフで見るスケール特性

接続数(Linux) アクセス集中時 avg(ms) 10k 50k 100k 0 20 40 60 10k / 11.1ms 50k / 27.1ms 100k / 51.0ms

接続数(Linux) ping/pong avg(ms) 10k 50k 100k 0.0 0.2 0.4 0.6 安定帯(0.2〜0.6ms) 10k / 0.227ms 50k / 0.348ms 100k / 0.553ms

接続数(Windows) ping/pong avg(ms) 10k 50k 0.0 0.5 1.0 10k / 0.378ms 50k / 0.507ms

● Linux:接続数 vs アクセス集中時レイテンシ

→ 10,000 → 100,000 接続で 10 倍の接続数に対し、平均レイテンシは約 4.6 倍に収まり、CPU割当なしとしては素直なスケールを示しています。

● Linux:接続数 vs ping/pong レイテンシ

→ 10万同時接続・ラウンド間隔なしでも 0.5〜0.6ms 程度に収まっており、連続バースト条件としては非常に安定した値です。

● Windows:接続数 vs ping/pong レイテンシ

→ スケジューラの重い Windows 環境でも、5万同時接続・ラウンド間隔なしで平均 1ms 程度に収まっており、OS 特性を踏まえると十分に良好な結果です。


Linux 版(アクセス集中時)

以下の表はハンドシェイクの重い処理(opening → header parse → handshake → SHA1Base64 → send())を接続維持しながら同時接続した場合の測定結果です。
つまり、メモリ管理(GC動作)やイベントループが全接続に対して常に実行されている状況での動作です。
アクセス集中時レイテンシ(単位:ms)
接続数 avg mid min max p90 p95
10,000 11.1423 10.1285 0.0801 31.9084 22.7463 24.7657
50,000 27.0608 25.9533 0.0752 85.1217 50.7054 53.9618
100,000 51.0224 49.8224 0.1773 214.3862 91.4050 100.9020
10,000 → 100,000 接続で約 10 倍の接続数に対し、平均レイテンシは約 4.6 倍に収まっています。CPU 割当なしでこのスケール特性は、実運用を考えると非常に良好な挙動です。

Linux 版 6 時間耐久テスト(ping/pong フレーム 100 バイト)

以下の表は上記ハンドシェイク後、各接続数に応じて ping/pong フレーム(ペイロード部 100 byte の送受信)で同時実行する動作を 6 時間経過するまで繰り返した状況での測定結果です。

10,000 同時接続(ラウンド間隔 10 秒)

ラウンド数 avg mid min max p90 p95
2,155 0.2269 0.2272 0.2039 0.2639 0.2320 0.2361

50,000 同時接続(ラウンド間隔なし)

ラウンド数 avg mid min max p90 p95
31,769 0.3484 0.3461 0.3090 0.4249 0.3673 0.3728

100,000 同時接続(ラウンド間隔なし)

ラウンド数 avg mid min max p90 p95
38,739 0.5531 0.5506 0.4930 0.6975 0.5753 0.5847
10,000 接続時はラウンド間隔 10 秒の「余裕のある条件」、50,000 / 100,000 接続時はラウンド間隔なしの「連続バースト条件」です。
それにもかかわらず、10万同時接続でも平均 0.55ms 程度に収まっており、CPU 割当なしとしては非常に安定した値です。

Windows 版(アクセス集中時)

以下の表はハンドシェイクの重い処理(opening → header parse → handshake → SHA1Base64 → send())を接続維持しながら同時接続した場合の測定結果です。
つまり、メモリ管理(GC動作)やイベントループが全接続に対して常に実行されている状況での動作です。
アクセス集中時レイテンシ(単位:ms)
接続数 avg mid min max p90 p95
10,000 20.9003 21.1037 0.1537 67.9925 38.6197 43.2785
50,000 36.0866 32.3841 0.1449 122.9753 63.8790 73.6337
※ Windows 版については、OS 標準設定のままでは 50,000 接続付近で WSAENOBUFS (10055)(参考:Microsoft Docs)が発生するため、本ページでは標準設定で安定動作する範囲(〜50,000 接続)を対象としています。これは OS 側の制約によるもので、サーバーアーキテクチャの限界ではありません。

Windows 版 6 時間耐久テスト(ping/pong フレーム 100 バイト)

以下の表は上記ハンドシェイク後、各接続数に応じて ping/pong フレーム(ペイロード部 100 byte の送受信)で同時実行する動作を 6 時間経過するまで繰り返した状況での測定結果です。

10,000 同時接続(ラウンド間隔 10 秒)

ラウンド数 avg mid min max p90 p95
2,149 0.3779 0.3741 0.3289 1.3451 0.3851 0.3899

50,000 同時接続(ラウンド間隔なし)

ラウンド数 avg mid min max p90 p95
21,483 0.5070 0.5054 0.4525 0.6242 0.5305 0.5380
Windows は Linux に比べてスケジューラやタイマのオーバーヘッドが大きくなりがちですが、5万同時接続・ラウンド間隔なしの条件でも平均 0.50ms 程度に収まっており、Windows 環境としては非常に安定した結果です。

ベンチマークツールと関連情報


ベンチマークツール

ハイパフォーマンスモードの特性を正しく測定するために、SOCKET-MANAGER では 専用のベンチマークツール を提供しています。
このツール自体もハイパフォーマンスモードで利用する方がより正確に測定できます。

リポジトリ

https://github.com/socket-manager/launcher

インストール
> composer create-project socket-manager/launcher
                

起動方法(簡易形式)

混雑状態ベンチ

接続数が増えた際のスケール特性を測定します。
> php worker app:concurrent-load-benchmark <サンプル数>
                        

純粋性能ベンチ

IO ドライバの純粋な処理性能を測定します。
> php worker app:pure-latency-benchmark <サンプル数>
                        

耐久テスト

長時間稼働時の安定性を測定します。
> php worker app:stress-test <サンプル数>
                        

フレームワーク本体


リポジトリ

https://github.com/socket-manager/library

インストール

通常は WebSocket プロジェクトなどの個別プロジェクトをインストールする際に 自動的に導入されます。

各プロジェクト内で以下を実行することで、ライブラリを最新バージョンへ更新できます。
> composer update socket-manager/library
                

おわりに

CPU割当なし・ラウンド間隔なしという厳しい条件下でも、SOCKET-MANAGER Framework は以下の特性を示しました。
  • 10万同時接続時でも ping/pong 平均 0.55ms 程度
  • 18,000〜20,000 rps 相当の実効スループットを維持(10,000 接続あたり 1,800〜2,000 rps)
  • 全テストでエラーゼロ
  • メモリは PHP 標準設定の 128MB のまま
  • 接続数 10倍に対してレイテンシは約 4.6倍に収まる線形スケール
これらの結果は、本フレームワークが 性能・堅牢性・軽量性の3要素を高いレベルで両立している ことを示しています。

FFI の独自 IO ドライバによるネイティブ級の性能を実現する機能については「ハイパフォーマンスモード」で詳しく解説しています。

▶ ハイパフォーマンスモードを見る

WebSocket と TCP のスケール特性を比較したい場合は、以下のページも参照してください。

▶ 純粋 TCP スケール性能を見る

フレームワーク全体の構成については「フレームワークのご紹介」をご覧ください。

▶ フレームワークのご紹介を見る