HTML WebSocketはクライアントごとに開いた接続を維持しますか?これはスケールしますか?


159

HTML WebSocketのスケーラビリティについて何か情報があれば教えてください。私が読んだすべてのことについて、すべてのクライアントはサーバーとのオープンな通信ラインを維持するようです。私はそれがどのようにスケーリングし、サーバーが処理できる開いているWebSocket接続の数を疑問に思っています。これらの接続を開いたままにしておくことは、実際には問題ではないかもしれませんが、問題はないようです。


1
HTML WebSocketのようなものはありません。あなたはHTTP WebSocketを意味します。
ローン侯爵

回答:


209

ほとんどの場合、WebSocketはAJAX / HTMLリクエストよりも拡張性が高いでしょう。ただし、これは、WebSocketがAJAX / HTMLのすべての用途の代わりになるという意味ではありません。

各TCP接続自体は、サーバーリソースをほとんど消費しません。多くの場合、接続の設定にはコストがかかりますが、アイドル状態の接続を維持することはほとんど無料です。通常発生する最初の制限は、同時に開くことができるファイル記述子(ソケットはファイル記述子を消費する)の最大数です。多くの場合、これはデフォルトで1024に設定されていますが、簡単に高く設定できます。

何万もの同時AJAXクライアントをサポートするようにWebサーバーを構成しようとしたことがありますか?それらのクライアントをWebSocketsクライアントに変更してください。

HTTP接続は、開いているファイルを作成したり、長期間ポート番号を消費したりしませんが、他のすべての点でコストが高くなります。

  • 各HTTP接続は、ほとんどの場合使用されない多くの手荷物を運びます:Cookie、コンテンツタイプ、一定の長さ、ユーザーエージェント、サーバーID、日付、最終変更日など。WebSocket接続が確立されると、アプリケーションが必要とするデータは、前後に送信する必要があります。

  • 通常、HTTPサーバーは、ディスクとCPU時間を使用するすべてのHTTPリクエストの開始と完了をログに記録するように構成されています。WebSocketsデータの開始と完了をログに記録することが標準になりますが、WebSockets接続が二重転送を行っている間は、追加のログオーバーヘッドはありません(そうするように設計されているアプリケーション/サービスを除く)。

  • 通常、AJAXを使用するインタラクティブアプリケーションは、継続的にポーリングするか、ある種のロングポーリングメカニズムを使用します。WebSocketsは、サーバーとクライアントが既存の接続を介してレポートする何かがある場合に互いに通知する、よりイベント化されたモデルを実行するはるかにクリーンな(そしてリソースが少ない)方法です。

  • 本番環境で人気のあるWebサーバーのほとんどには、HTTP要求を処理するためのプロセス(またはスレッド)のプールがあります。各プロセス/スレッドは一度に1つのHTTPリクエストを処理するため、プレッシャーが高まると、プールのサイズが増加します。プロセス/スレッドを追加するたびに、より多くのメモリが使用され、新しいプロセス/スレッドの作成は、新しいソケット接続の作成(これらのプロセス/スレッドがまだ実行する必要がある)よりもかなりコストがかかります。人気のあるWebSocketsサーバーフレームワークのほとんどは、スケーリングとパフォーマンスが向上する傾向があるイベントのルートを進んでいます。

WebSocketの主な利点は、インタラクティブなWebアプリケーションの接続でレイテンシが低くなることです。HTTP AJAX / long-poll(アプリケーション/サーバーが適切に設計されていると想定)よりもスケーリングが向上し、サーバーリソースの消費が少なくなりますが、IMOの遅延が少ないことがWebSocketsの主な利点です。 AJAX /ロングポールの現在のオーバーヘッドと待ち時間。

WebSockets標準がさらに完成し、幅広いサポートが提供されるようになると、サーバーと頻繁に通信する必要があるほとんどの新しいインタラクティブなWebアプリケーションで使用することは理にかなっています。既存のインタラクティブなWebアプリケーションの場合、それは現在のAJAX / long-pollモデルがどれだけうまく機能しているかに本当に依存します。変換するのは簡単なことではないので、多くの場合、コストは利益に値しません。

更新

便利なリンク:Node.jsを使用したAWSでの600k同時WebSocket接続


4
素晴らしいアンサー。お返事をいただきありがとうございます。
ライアンモンゴメリー

7
ただし、壁にぶつかった後のスケーリング方法はまだわかりません。WebSocketはより少ないリソース(垂直方向にスケーリング)を消費することは事実ですが、HTTPは水平方向にスケーリングするのに最適です。理論的にはサーバーを追加して無限に拡張できます。1つのボックスの容量を使い切った後の拡張方法については、いつも混乱していました。考え?
ショーンクラークヘス

6
@Sean。WebSocketは、必ずしも水平方向のスケーリングが悪いわけではありません。必ずしもそれほど簡単に拡張できない新しいアプリケーションを開くだけです。たとえば、静的データを提供する場合、一連のWebSocketサーバーは、一連のHTTPサーバーと同じかそれ以上(またはそれ以上)スケーリングします。低レイテンシのリアルタイムゲームは、トランスポートに関係なくスケーリングするのが困難です(そして、HTTPを使用して実際に実行することはできません)。本当の問題は、データ/アプリケーションがどれだけうまく拡張できるかです。そのスケール場合は、WebSocketを対HTTPのあなたの選択は、他の要因に基づいている必要があります:レイテンシー、展開オプション、ブラウザのサポート、など
kanaka

2
1つの修正-TCP接続は宛先IPと宛先ポートで構成されます。つまり、±64kポートの制限は、実際には単一のクライアントに対してのみです。理論的には、サーバーはオープンな接続をいくつでも持つことができ、ハードウェアによってのみ制限されます。
2013

@リゾン、それは本当だ。回答を更新し、オープンポートの制限を変更しました。代わりに、最初によく遭遇するファイル記述子の制限について言及しました。
kanaka

36

明確化:サーバーがサポートできるクライアント接続の数は、このシナリオのポートとは何の関係もありません。サーバーは[通常] 1つのポートでWS / WSS接続のみをリッスンしているためです。他のコメンターが参照するつもりだったのはファイル記述子だったと思います。ファイル記述子の最大数をかなり高く設定できますが、その場合、開いているTCP / IPソケットごとに合計されるソケットバッファーサイズに注意する必要があります。ここにいくつかの追加情報があります:https : //serverfault.com/questions/48717/practical-maximum-open-file-descriptors-ulimit-n-for-a-high-volume-system

WSとHTTPによる遅延の減少については、最初のWSハンドシェイクを超えてHTTPヘッダーの解析が行われないため、それは事実です。さらに、より多くのパケットが正常に送信されると、TCP輻輳ウィンドウが広がり、RTTを効果的に削減します。


AFAIRには1つの着信ポートがありますが、接続ごとに常に1つの発信ポートが開かれます。これは実際、C10k問題の一部にすぎません。
Arnaud Bouchez 2014

14

最新の単一サーバーは、一度に数千のクライアントを処理できます。そのHTTPサーバーソフトウェアは、イベント駆動型(IOCP)指向である必要があります(以前のApacheでは、1つの接続= 1つのスレッド/プロセス方程式ではなくなりました)。Windows(http.sys)に組み込まれたHTTPサーバーでさえ、IOCP指向で非常に効率的です(カーネルモードで実行)。この観点から見ると、WebSocketと通常のHTTP接続との間のスケーリングに大きな違いはありません。1つのTCP / IP接続は少しのリソース(スレッドよりもはるかに少ない)を使用し、最新のOSは多数の同時接続を処理するように最適化されています。WebSocketとHTTPは、このTCP / IP仕様から継承した単なるOSI 7アプリケーションレイヤープロトコルです。

しかし、実験から、WebSocketに関する2つの主要な問題を見てきました。

  1. CDNはサポートされていません。
  2. 彼らは潜在的なセキュリティ問題を抱えています。

したがって、どのプロジェクトでも、以下をお勧めします。

  • クライアント通知のみにWebSocketを使用します(ロングポーリングへのフォールバックメカニズムを使用-多くのライブラリーがあります)。
  • その他のすべてのデータには、RESTful / JSONを使用し、キャッシュにはCDNまたはプロキシを使用します。

実際には、完全なWebSocketsアプリケーションはうまく拡張できません。WebSocketを設計して、サーバーからクライアントにプッシュ通知を送信します。

WebSocketの使用に関する潜在的な問題について:

1. CDNの使用を検討する

今日(ほぼ4年後)、Webスケーリングでは、静的コンテンツ(html、css、js)だけでなく(JSON)アプリケーションデータにコンテンツ配信ネットワーク(CDN)フロントエンドを使用する必要があります

もちろん、すべてのデータをCDNキャッシュに保存するわけではありませんが、実際には、多くの一般的なコンテンツが頻繁に変更されることはありません。RESTリソースの80%がキャッシュされる可能性があると思います... 1分(または30秒)のCDN有効期限タイムアウトでも、中央サーバーに新しいライブを提供し、アプリケーションの応答性を大幅に向上させることができます。地理的に調整される...

私の知る限りでは、CDNにはまだWebSocketsのサポートはありません。WebSocketはステートフルですが、HTTPはステートレスであるため、非常に簡単にキャッシュできます。実際、WebSocketをCDN対応にするために、ステートレスなRESTfulアプローチに切り替える必要があるかもしれません...これはWebSocketではありません。

2.セキュリティの問題

WebSocketには、特にDOS攻撃に関する潜在的なセキュリティ問題があります。新しいセキュリティの脆弱性についての説明このスライドのセットこのWebkitチケットを参照してください。

WebSocketは、あらゆるビジネスセキュリティにおいて、今日かなり標準となっているOSI 7アプリケーションレイヤーレベルでのパケット検査の可能性を回避します。実際、WebSocketは送信を難読化するため、セキュリティリークの重大な違反となる可能性があります。


2
@ArnaudBouchez-CDNの素晴らしい説明の+1。簡単なフォローアップ質問-イベント配信ネットワークの実現可能性についてどう思いますか?CDNに倣ってパターン化されていますが、WebSocketなどのまだ目に見えない技術を介してストリーミングデータなどを配信することを目的としています。
quixver 2014年

8

このように考えてください。何がより安価で、開いている接続を維持するか、またはすべての要求に対して新しい接続を開く(そうすることのネゴシエーションオーバーヘッドがあるので、TCPであることに注意してください)。

もちろん、それはアプリケーションに依存しますが、長期間のリアルタイム接続(AJAXチャットなど)の場合は、接続を開いたままにしておく方がはるかに優れています。

接続の最大数は、ソケットの空きポートの最大数によって制限されます。


WebSocketを使用せずに接続を開いたままにすることができます(HTTP / 1.1のkeep aliveオプションのおかげです)。私はあなたのここでのポイントを理解しているとは思いません。
Arnaud Bouchez 2014

1
+1。TCP接続の設定にはsyn / ack / ackが必要であり、TLSではキー交換のためにさらに多くのラウンドトリップが必要になることを忘れがちです。
quixver 2014年

1
@ArnaudBouchezチェックen.wikipedia.org/wiki/HTTP_persistent_connection#HTTP_1.1 WebSocketは、必要な限り開いていて、ハッキングされていない(ロングポーリングやその他の代替手段など)。
kaoD 2015

-5

いいえ、スケーリングしません。中間ルートスイッチに多大な作業を提供します。次に、サーバー側でページフォールト(これらの記述子をすべて保持する必要があります)が高い値に達し、リソースを作業領域に取り込む時間が増加します。これらはほとんどがJavaで記述されたサーバーであり、ソケットのガジリオンを保持してから破壊または作成する方が速い場合があります。このようなサーバーをマシンで実行すると、他のプロセスは移動できなくなります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.