web-dev-qa-db-ja.com

現代のHTTPキープアライブ

そのため、httpについて1つまたは2つのことを知っているhaproxyの著者によると:

キープアライブは、CPUが100倍遅くなったときにサーバーのCPU使用率を削減するために考案されました。しかし、言われていないことは、永続的な接続は多くのメモリを消費しますが、それらを開いたクライアント以外は誰も使用できないということです。 2009年の今日、CPUは非常に安価であり、メモリはアーキテクチャまたは価格によって依然として数ギガバイトに制限されています。サイトがキープアライブを必要とする場合、実際の問題があります。負荷の高いサイトでは、多くの場合、キープアライブを無効にして、同時クライアントの最大数をサポートします。キープアライブがないことの本当の欠点は、オブジェクトをフェッチするためのレイテンシがわずかに増加することです。これを補うために、ブラウザは非キープアライブサイトの同時接続数を2倍にします。

http://haproxy.1wt.eu/ から)

これは他の人々の経験と一致していますか?すなわち、キープアライブなし-結果はほとんど気づかないのですか? (おそらく、websocketsなどでは、キープアライブステータスに関係なく接続が「開かれた」ままであることに注意してください-非常に応答性の高いアプリの場合)。サーバーから離れた場所にいる人、またはページをロードするときに同じホストからロードするアーティファクトが多い場合、効果は大きくなりますか? (CSS、画像、JSなどは、キャッシュフレンドリーなCDNからますます増えていると思います)。

考え?

(これがserverfault.comのものかどうかはわかりませんが、誰かがそれをそこに移動するように指示するまで、クロスポストしません)。

92
Michael Neale

私はこの引用の著者であるので、私は応答します:-)

大規模サイトには、同時接続と待機時間という2つの大きな問題があります。同時接続は、コンテンツのダウンロードに時間がかかる低速のクライアントと、アイドル状態の接続が原因です。これらのアイドル接続状態は、キープアライブと呼ばれる複数のオブジェクトを取得するための接続の再利用が原因で発生します。クライアントがサーバーに非常に近い場合、接続を集中的に使用し、ほとんどアイドル状態にならないようにすることができます。ただし、シーケンスが終了すると、だれもすぐにチャネルを閉じようとはせず、接続は開いたままで長時間使用されません。これが、多くの人々が非常に低いキープアライブタイムアウトの使用を提案する理由です。 Apacheのような一部のサーバーでは、設定できる最小のタイムアウトは1秒であり、高負荷に耐えるには多すぎることがよくあります。前に20000のクライアントがあり、1秒に平均1つのオブジェクトをフェッチする場合、これらの20000接続を永続的に確立します。 Apacheのような汎用サーバーでの20000同時接続は巨大で、32 GBから64 GBのRAMがロードされるモジュールに応じて必要になります。実際には、20000クライアントの場合、フェッチするオブジェクトが多数あるとブラウザーは2〜3の接続を設定しようとするため、サーバー上に40000〜60000の同時接続が表示される場合があります。

各オブジェクトの後に接続を閉じると、同時接続の数は劇的に減少します。実際、オブジェクト間の時間でオブジェクトをダウンロードする平均時間に対応する係数だけ低下します。オブジェクト(ミニチュア写真、ボタンなど)をダウンロードするのに50ミリ秒が必要で、上記のように1秒あたり平均1つのオブジェクトをダウンロードする場合、クライアントごとに0.05の接続しかありません。 20000クライアントの同時接続。

これで、新しい接続を確立する時間が重要になります。遠くのリモートクライアントでは、不快な遅延が発生します。過去に、キープアライブが無効にされている場合、ブラウザは大量の同時接続を使用していました。私は、MSIEの4とNetscapeの8の数字を覚えています。これは、実際にオブジェクトごとの平均レイテンシーをそれだけで割ったはずです。キープアライブがあらゆる場所に存在するようになったため、リモートサーバーの負荷がさらに増加し​​、ブラウザーがインターネットのインフラストラクチャの保護を担当するため、これほど大きな数字は見られません。

つまり、今日のブラウザでは、キープアライブサービスと同じくらい非キープアライブサービスの応答性を高めることが難しくなります。また、一部のブラウザー(例:Opera)は、ヒューリスティックを使用して、ピペリニングを使用しようとします。パイプライン処理は、応答を待たずに複数の要求を送信することで遅延をほぼ排除するため、キープアライブを使用する効率的な方法です。 100枚の小さな写真があるページで試してみましたが、最初のアクセスはキープアライブなしの約2倍の速さですが、次のアクセスは約8倍の速さです。 「304」応答)。

理想的には、取得したオブジェクト間の接続を維持し、ページが完了したらすぐにそれをドロップするために、ブラウザに調整可能なパラメータをいくつか用意する必要があります。しかし、残念ながらそれは見ていません。

このため、Apacheなどの汎用サーバーをフロントサイドにインストールする必要があり、大量のクライアントをサポートする必要があるサイトでは、通常、キープアライブを無効にする必要があります。また、ブラウザが接続数を増やすように強制するために、ダウンロードを並列化できるように複数のドメイン名を使用します。 SSLを集中的に使用するサイトでは特に問題になります。これは、1回のラウンドトリップが追加されるため、接続設定がさらに高くなるためです。

最近よく見られるのは、そのようなサイトがhaproxyやnginxなどの軽いフロントエンドをインストールすることを好むことです。これらは、数万から数十万の同時接続を問題なく処理し、クライアント側でキープアライブを有効にし、 Apache側。一方、接続を確立するためのコストはCPUの観点からはほとんどゼロであり、時間の観点ではまったく目立ちません。このようにして、これは両方の長所を提供します。クライアント側でのタイムアウトが非常に低いキープアライブによる低遅延、およびサーバー側での接続数の減少。誰もが満足しています :-)

一部の商用製品は、フロントロードバランサーとサーバー間の接続を再利用し、それらを介してすべてのクライアント接続を多重化することにより、これをさらに改善します。サーバーがLBに近い場合、以前のソリューションよりもゲインはそれほど高くありませんが、複数のユーザー間の接続の予期しない共有によるユーザー間のセッションクロスのリスクがないことを保証するために、アプリケーションの調整が必要になることがよくあります。理論的には、これは決して起こらないはずです。現実は大きく異なります:-)

140
Willy Tarreau

これが書かれてから(そしてここでstackoverflowに投稿されて)数年で、nginxのような人気が高まっているサーバーがあります。

たとえば、nginxは、RAMが2.5 MB(メガバイト)の単一プロセスで、10,000個のキープアライブ接続を開いたままにできます。実際、ごくわずかなRAMで何千もの接続を開いたままにするのは簡単で、ヒットする唯一の制限は、開いているファイルハンドルの数やTCP接続などの他の制限です。

キープアライブは、キープアライブの仕様自体の問題ではなく、Apacheのプロセスベースのスケーリングモデルと、キープアライブがアーキテクチャに対応するように設計されていないサーバーにハッキングされたための問題でした。

特に問題になるのは、Apache Prefork + mod_php + keep-alivesです。これは、完全にアイドル状態であり、キープアライブとしてのみ開いている場合でも、すべての単一の接続がRAMプロセスが占有するすべてのPHPを占有し続けるモデルです。これはスケーラブルではありません。ただし、サーバーをこのように設計する必要はありません-サーバーがすべてのキープアライブ接続を個別のプロセスに保持する必要がある特別な理由はありません(特に、そのようなプロセスに完全なPHPインタープリターがある場合はそうではありません)。 PHP-FPMとnginxのようなイベントベースのサーバー処理モデルは、問題をエレガントに解決します。

2015年更新:

SPDYとHTTP/2は、HTTPのキープアライブ機能をさらに優れたものに置き換えます。接続を維持し、その上で複数の要求と応答を行うだけでなく、多重化されるため、応答を任意の順序で送信できます。 、要求された順序だけでなく、並行して。これにより、遅い応答が高速な応答をブロックするのを防ぎ、ブラウザーが単一サーバーへの複数の並列接続を開いたままにする誘惑を取り除きます。これらの技術は、mod_phpアプローチの不備と、PHP-FPMのようなものと別個に結合されたイベントベース(または少なくともマルチスレッド)Webサーバーのようなものの利点をさらに強調します。

22
thomasrutter

私の理解では、CPUとはほとんど関係ありませんでしたが、世界の反対側に繰り返しソケットを開く際の遅延です。帯域幅が無限であっても、接続遅延によりプロセス全体が遅くなります。ページに多数のオブジェクトがある場合に増幅されます。永続的な接続でも要求/応答の待ち時間がありますが、平均して2つのソケットがある場合は、一方がデータをストリーミングし、もう一方がブロックする可能性があるため、ソケットのレイテンシは減少します。また、ルーターはソケットに接続することを前提として、書き込みを許可します。完全な往復ハンドシェイクが必要です。繰り返しますが、私は専門家であると主張することはありませんが、これは私がいつもそれを見た方法です。本当にクールなのは、完全に非同期のプロトコルです(いいえ、完全に病気のプロトコルではありません)。

2
catchpolenet

CloudFrontやCloudFlareなどの「Origin pull」CDNを使用している場合、非常に長いキープアライブが役立ちます。実際、完全に動的なコンテンツを提供している場合でも、これはCDNなしよりも高速であることがわかります。

各PoPが基本的にサーバーに永続的に接続するようにキープアライブが長い場合、ユーザーが初めてサイトにアクセスしたときに、ローカルPoPの代わりに高速のTCPハンドシェイクを行うことができますあなたとの遅いハンドシェイク(光自体は、ファイバーを介して世界中を半周するのに約100msかかり、TCP接続を確立するには3つのパケットをやり取りする必要があります。 SSLにはthree往復が必要です

2
mjs