web-dev-qa-db-ja.com

RESTful HTTPの代わりにWebsocketを使用する場合の落とし穴は何ですか?

私は現在、クライアントが大きな仕事を要求し、それをサーバーに送信する必要があるプロジェクトに取り組んでいます。次に、サーバーはジョブを分割し、クライアントがURLの配列で応答してGET呼び出しを行い、データをストリームバックします。私はプロジェクトのグリーンホーンであり、現在、効率を向上させるためにSpring WebSocketを使用しています。クライアントが常にサーバーにpingを送信して、結果をストリーミングバックできるかどうかを確認する代わりに、websocketはクライアントhoorayに直接接続します。

プロセス全体をWebsocketで管理するのは悪い考えでしょうか? Spring WebsocketでSTOMPを使用していますが、RESTを捨てることにはまだ大きな問題がありますか?

53

RESTful HTTPでは、クライアントがリクエストを送信し、サーバーがレスポンスを返すステートレスリクエスト/レスポンスシステムがあります。

WebSocketを使用すると、どちらかの方法でメッセージを送信できるステートフル(または潜在的にステートフル)メッセージパッシングシステムがあり、特定のメッセージの送信はRESTful HTTP要求/応答よりもオーバーヘッドが低くなります。

この2つは、強度が異なるかなり異なる構造です。

接続されたwebSocketの主な利点は次のとおりです

  1. 双方向通信したがって、サーバーはいつでもクライアントに何かを通知できます。そのため、一定の間隔でサーバーをポーリングして新しいものがあるかどうかを確認する代わりに、クライアントはwebSocketを確立し、サーバーからのメッセージをリッスンするだけで済みます。サーバーの観点から見ると、クライアントに関心のあるイベントが発生すると、サーバーは単にメッセージをクライアントに送信します。サーバーはプレーンHTTPでこれを実行できません。

  2. メッセージあたりのオーバーヘッドが低い。クライアントとサーバー間で大量のトラフィックが流れると予想される場合、webSocketを使用するとメッセージあたりのオーバーヘッドが低くなります。これは、TCP接続がすでに確立されており、既に開いているソケットでメッセージを送信するだけでよいためです。 HTTP RESTリクエストでは、最初にクライアントとサーバー間を行き来するTCP接続を確立する必要があります。次に、HTTP要求を送信し、応答を受信して​​、TCP接続を閉じます。 HTTPリクエストには、特定のリクエストに関係のないものであっても、そのサーバーに合わせられたすべてのCookieなどのオーバーヘッドが必ず含まれます。 HTTP/2(最新のHTTP仕様)では、単一のTCP接続を複数の要求/応答以上に使用できるため、クライアントとサーバーの両方で使用されている場合、この点でさらに効率が向上します。 https TCPリクエスト/レスポンスを作成するためにRESTレベルで進行中のすべてのリクエスト/レスポンスをチャート化すると、送信と比較してどれだけの量が発生するか驚かれることでしょうすでに確立されているwebSocketを介したメッセージ。

  3. 状況によってはより高いスケール。メッセージあたりのオーバーヘッドが低く、新しいものを見つけるためのクライアントポーリングがないため、スケーラビリティが向上します(特定のサーバーが処理できるクライアントの数が増える)。 webSocketのスケーラビリティにも欠点があります(以下を参照)。

  4. ステートフル接続。 CookieとセッションIDに頼らずに、特定の接続の状態をプログラムに直接保存できます。ほとんどの問題を解決するためにステートレス接続を使用して多くの開発が行われていますが、ステートフル接続を使用する方が単純な場合もあります。

RESTful HTTPリクエスト/レスポンスの主な利点は次のとおりです

  1. ユニバーサルサポート。 HTTPよりも広くサポートされることは困難です。現在、webSocketsは比較的良好なサポートを享受していますが、webSocketサポートが定期的に利用できない状況がまだあります。

  2. より多くのサーバー環境と互換性があります。長時間実行されるサーバープロセスを許可しないサーバー環境があります(一部の共有ホスティング状況)。これらの環境はHTTPリクエストをサポートできますが、長時間実行されるwebSocket接続はサポートできません。

  3. 状況によってはより高いスケール。連続接続TCPソケットのwebSocket要件は、HTTPリクエストが要求しないサーバーインフラストラクチャにいくつかの新しいスケール要件を追加します。したがって、これは結局トレードオフのスペースになります。 webSocketの利点が実際に必要とされない、または重要な方法で使用されていない場合、HTTPリクエストは実際に拡張される可能性があります。それは間違いなく特定の使用プロファイルに依存します。

  4. 1回限りのrequest/responseの場合、webSocketを確立し、使用してから閉じるよりも、単一のHTTPリクエストの方が効率的です。これは、webSocketを開くにはHTTPリクエスト/レスポンスで開始し、双方がwebSocket接続へのアップグレードに同意した後、実際のwebSocketメッセージを送信できるためです。

  5. ステートレスステートレスなインフラストラクチャを使用してジョブをより複雑にしない場合、ステートレスな世界ではスケーリングがはるかに簡単になります(ロードバランサーの背後にサーバープロセスを追加するだけです)。

  6. 自動的にキャッシュ可能適切なサーバー設定を使用すると、ブラウザまたはプロキシによってhttp応答をキャッシュできます。 webSocketsを介して送信されるリクエストには、このような組み込みのメカニズムはありません。


だから、あなたが質問をした方法に対処するには:

RESTful HTTPの代わりにwebsocketを使用する場合の落とし穴は何ですか?

  1. 大規模(数十万のクライアント)では、同時に接続された多数のwebSocketをサポートするために、特別なサーバー作業が必要になる場合があります。

  2. 考えられるすべてのクライアントまたはツールセットは、HTTPリクエストをサポートするのと同じレベルでwebSocketまたはそれらを介して行われたリクエストをサポートしません。

  3. 安価なサーバー環境の中には、webSocketのサポートに必要な長時間実行されるサーバープロセスをサポートしていないものもあります。

アプリケーションが進行状況の通知をクライアントに返すことが重要な場合は、継続的な進行状況を送信しながら長時間実行されるHTTP接続を使用するか、webSocketを使用できます。 webSocketの方が簡単です。この特定のアクティビティの比較的短い期間にのみwebSocketが本当に必要な場合は、クライアントにデータをプッシュする機能が必要な期間にのみwebSocketを使用することで、最良の全体的なトレードオフセットが見つかることがあります。その後、通常のリクエスト/レスポンスアクティビティにhttpリクエストを使用します。

94
jfriend00

それは本当にあなたの要件に依存します。 RESTサービスは、Websocketsと比較して、開発者がはるかに透過的で簡単に選択できます。

Websocketを使用すると、URIを介してリソースを参照する機能など、RESTful Webサービスが提供する利点のほとんどが削除されます。本当にすべきことは、RESTとハイパーメディアの利点を理解し、それに基づいてそれらの利点があなたにとって重要かどうかを判断することです。

もちろん、RESTful Webサービスを作成し、リアルタイム応答用のWebSocketベースのAPIを追加することも完全に可能です。

しかし、制御された環境で自分だけが使用するサービスを作成する場合、唯一の欠点は、すべてのクライアントがWebSocketをサポートしているわけではなく、ほとんどすべてのタイプの環境が単純なhttp呼び出しを実行できることです。

3
Evert