ホームページ >ウェブフロントエンド >htmlチュートリアル >http パフォーマンスに影響を与える一般的な要因を分析する
この記事の主な内容は、HTTP のパフォーマンスに影響を与える一般的な要因を紹介することです。一定の参考価値があるため、興味のある友人はそれについて学ぶことができます。
ここで説明する HTTP パフォーマンスは、単一サーバーの HTTP パフォーマンスという最も単純なモデルに基づいています。もちろん、大規模な負荷分散クラスターにも適用できます。結局のところ、このクラスターはまた、複数の HTTP サーバーで構成されます。また、クライアントやサーバー自体の負荷が高すぎることや、HTTP プロトコルを実装するソフトウェアが異なる IO モデルを使用していることも除外し、DNS 解決プロセスや Web アプリケーション開発自体の欠陥も無視します。
TCP/IP モデルの観点から見ると、HTTP の下位層は TCP 層であるため、HTTP のパフォーマンスは TCP のパフォーマンスに大きく依存します。もちろん、HTTPS であれば、TLS/ SSL 層を追加する必要がありますが、追加することはできます HTTPS のパフォーマンスが HTTP よりも明らかに悪いのは確かです 通信プロセスについてはここでは説明しません つまり、層が増えるほど、パフォーマンスの低下は深刻になりますなれ。
上記の条件下で、HTTP パフォーマンスに影響を与える最も一般的な要因は次のとおりです。
TCP 接続の確立 (3 ウェイ ハンドシェイク フェーズ)
TCP スロー スタート
TCP 遅延確認
TCP 接続の確立
2が制限されます。では、なぜスタートが遅いのでしょうか?大規模なデータ伝送によるネットワークの麻痺を防ぐことが主な目的ですが、インターネット上のデータ伝送において非常に重要なリンクはルーターですが、ルーター自体は高速ではありません。インターネットが送信され、ルーティングと転送が必要になる場合があります。一定期間内にルーターに到着するデータの量が送信量よりはるかに多い場合、ルーターはローカル キャッシュが空になったときにデータ パケットを破棄します。この破棄動作は輻輳と呼ばれます。ルータがこの状況に遭遇すると、多くのリンクに影響を及ぼし、深刻な場合には広範な麻痺につながる可能性があります。したがって、TCP 通信を行うすべての当事者は輻輳制御を実行する必要があり、スロー スタートは輻輳制御のアルゴリズムまたはメカニズムの 1 つです。 あなたは状況を想像します。TCP には再送信メカニズムがあることがわかっています。ネットワーク内のルーターが輻輳により大規模なパケット損失を経験すると仮定します。データの送信側として、ルーターの TCP プロトコル スタックはこの状況を確実に検出します。次に、TCP 再送信メカニズムが開始され、このルータの影響を受ける送信者はあなただけではないはずです。すると、多数の送信者 TCP プロトコル スタックが再送信を開始します。これは、元々混雑していたネットワークでさらに多くのデータを送信することと同じです。 、これは火に油を注ぐようなものです。 上記の説明から、通常のネットワーク環境であっても、HTTP メッセージの送信者と TCP 接続を確立するための各リクエストはスロー スタートの影響を受けるため、HTTP によれば、短い接続 1 セッション 終了すると切断されます。クライアントが HTTP リクエストを開始し、Web ページ上のリソースを取得したところ、HTTP が切断されたと想像できます。TCP 接続が、セッションが完了する前に切断された可能性があります。 TCP スロー スタート プロセスが完了しました。その後、他の Web ページが後続のリソースで TCP 接続の確立を継続し、各 TCP 接続にスロー スタート フェーズが発生します。このパフォーマンスは想像できるため、パフォーマンスを向上させるために、HTTP 永続的を有効にすることができます接続、これは後述するキープアライブです。
確認メッセージは通常比較的小さい、つまり 1 つの IP グループで複数の確認メッセージを伝送できるため、小さなメッセージが送信されすぎないように、受信者は確認メッセージを送り返すときに様子を見ます。受信者にデータを送信しますか?その場合は、確認メッセージとデータを TCP セグメントにまとめて送信します。特定の時間内 (通常は 100 ~ 200 ミリ秒) に送信する必要がある他のデータがない場合、次に、確認メッセージを別のパケットで送信します。実際、これを行う目的は、ネットワークの負担を可能な限り軽減することです。
一般的な例は物流です。トラックの積載量は決まっています。積載量が 10 トンで、A 都市から B 都市に移動する場合、必ず同じように満載したいと考えます。小さな荷物を持って、すぐに立ち上がって都市 B まで車で行きます。
したがって、TCP はデータ パケットが来たときにすぐに ACK 確認を返すようには設計されていません。通常、パケットは一定期間キャッシュに蓄積されます。同じ方向のデータがまだある場合は、ACK 確認を送り返します。ただし、あまり長く待つことはできません。そうしないと、相手はパケットが失われたと判断し、相手からの再送信をトリガーします。
遅延確認を使用するかどうか、またどのように使用するかについては、オペレーティング システムによって意見が異なります。たとえば、Linux は有効または無効にすることができます。無効にするということは、遅延確認をそれぞれ確認することを意味します。これは高速確認モードでもあります。
有効にするかどうか、または設定するミリ秒数はシナリオによって異なることに注意してください。たとえば、オンライン ゲームのシナリオでは、確認をできるだけ早く行う必要があり、遅延した確認は SSH セッションに使用できます。
HTTP の場合、TCP 遅延確認をオフにするか調整できます。
このアルゴリズムは、実際には、IP パケットの使用率を向上させ、ネットワークの負荷を軽減するように設計されていますが、それでも小さなパケットとフルサイズのパケットが含まれます (イーサネット標準によると、MTU はメッセージあたり 1500 バイトです) 、1500 未満のメッセージは非フルサイズ メッセージとみなされます)。ただし、IP ヘッダーと TCP ヘッダーはそれぞれ 20 バイトを占めるため、小さなメッセージがどんなに小さくても 40 バイト未満にはなりません。 50 バイトの小さなメッセージを送信する場合、実際には有効なデータが少なすぎることを意味します。遅延確認応答と同様に、小さなサイズのパケットは LAN では大きな問題にはなりませんが、主に WAN に影響を与えます。
このアルゴリズムは、実際には、送信者が現在の TCP 接続でメッセージを送信したが、まだ確認を受け取っていない場合、送信者に送信すべき小さなメッセージがまだある場合は、それらを送信できないというものです。確認を受信した後、送信側は同じ方向の小さなメッセージをキャッシュに収集し、1 つのメッセージにまとめて送信します。実際、これは、受信者が ACK 確認を返すのが速いほど、送信者はより速くデータを送信できることを意味します。
ここで、確認の遅れと Nagle のアルゴリズムの組み合わせが引き起こす問題について話しましょう。実際、確認の遅延により、受信側は一定期間 ACK 確認を蓄積し、その間に ACK を受信しない場合、送信側は残りの非フルサイズ データの送信を継続しないことが容易にわかります。パケット(データは複数のIPパケットに分割されています。送信側が送信する応答データのパケット数は1500の整数倍にはなりません。データの末尾に小さいデータがある可能性が高くなります)ここでの矛盾は、この種の問題が TCP 送信の送信パフォーマンスに影響を与えるということです。そうすると、HTTP は TCP に依存しているため、当然 HTTP のパフォーマンスに影響します。通常はサーバー上のアルゴリズムを無効にします。このアルゴリズムを無効にするには、オペレーティング システムまたは HTTP でプログラムに TCP_NODELAY を設定して無効にすることができます。たとえば、Nginx では、tcp_nolay on;
を使用してこれを無効にできます。
これは、クライアントである当事者、または TCP 接続を積極的に閉じる当事者を指しますが、サーバーもイニシアチブ クローズを開始しますが、ここで説明しているのは HTTP パフォーマンスです。HTTP 接続の特性により、クライアントは通常、アクティブなクローズを開始します。
クライアントは HTTP リクエストを開始します (ここでは特定のリソースについて話しています)いわゆるホームページを開く代わりにリクエストを実行します。ホームページには N 個のリソースがあるため、N 個の HTTP リクエストが開始されます。)このリクエストが完了すると、TCP 接続が切断され、クライアント上の接続の TCP ステータスが表示されます。 . TIME_WAIT と呼ばれる状態。この状態から最終的なシャットダウンまでは、通常 2MSL4 かかります。クライアントがサーバーの HTTP サービスにアクセスするとき、独自のランダムな高ビット ポートを使用することがわかっています。サーバーの 80 または 443 ポートに接続して HTTP 通信 (本質は TCP 通信) を確立するため、クライアントの使用可能なポートの数が消費されます。クライアントが切断されると、このランダムなポートは解放されます。ただし、このランダムなポートは解放されます。クライアントがアクティブに切断した後、TCP ステータス TIME_WAIT から実際の CLOSED までの 2MSL 期間中、ランダム ポートは使用されません (クライアントが同じサーバーへの HTTP アクセスを再度開始した場合)。その目的の 1 つは、ダーティ データがサーバー上に送信されるのを防ぐことです。同じ TCP ソケットです。上記の結論から、クライアントのサーバーへの HTTP アクセスが集中しすぎると、ポートの使用速度がポートの解放速度よりも高くなる可能性があり、最終的には使用可能なランダム アクセスが存在しないために接続の確立に失敗する可能性があることがわかります。ポート。
通常、クライアントは積極的に接続を閉じると上で述べました。
TCP/IP 詳細解説第 1 巻 第 2 版、P442 の最後の段落には、対話型アプリケーションの場合、クライアントは通常、アクティブ シャットダウン操作を実行して TIME_WAIT 状態に入り、サーバーは通常、パッシブ シャットダウン操作を実行すると書かれています。直接 TIME_WAIT 状態にはなりません。
ただし、Web サーバーでキープアライブが有効になっている場合、タイムアウトに達するとサーバーは自動的にシャットダウンします。 (ここでの TCP/IP の詳細な説明が間違っていると言っているわけではありませんが、このセクションでは主に TCP について説明しており、HTTP については紹介していません。また、必然的ではなく通常と書かれています)
私は Nginx を使用していますテストを行って、構成ファイルに keepalive_timeout 65s;
を設定しました。Nginx のデフォルト設定は 75 秒です。これを 0 に設定すると、以下に示すようにキープアライブが無効になります:
以下では、Chrom ブラウザを使用して Nginx がデフォルトで提供するホームページにアクセスし、以下に示すように、パケット キャプチャ プログラムを通じて通信プロセス全体を監視します。 #上の図から、有効なデータ送信が完了した後、途中で Keep-Alive マークが付けられた通信が表示され、65 秒以内に要求がない場合にサーバーが積極的に切断することがわかります。 Nginx サーバー上の TIME_WAIT ステータスが表示されます。
サーバー ポートが枯渇しました
Nginx は 80 または 443 をリッスンするという人もいます。クライアントは常にこのポートに接続します。サーバーはどのようにポートを終了できるでしょうか?下の図のように (図の TIME_WAIT は無視してください。この理由は上で述べたように、Nginx の keepalive_timeout 設定が原因です)実際には、Nginx の動作に依存します。これは、実際のリソースやデータが Tomcat などのバックエンド Web アプリケーション上にあることを意味します。プロキシ モードの特徴は、プロキシ サーバーがユーザーに代わってバックエンドにアクセスしてデータを取得することです。このとき、バックエンド サーバーと比較すると、Nginx はクライアントになります。このとき、Nginx はランダムなポートを使用してデータを取得します。バックエンドへのリクエストを開始すると、システムが利用可能になります ランダムなポート範囲は確実です。
sysctl net.ipv4.ip_local_port_rangeコマンドを使用して、サーバー上のランダムなポート範囲を表示できます。
前に導入した遅延確認、Nagle アルゴリズム、およびプロキシ モードを通じて、Nginx はバックエンドのクライアントとして機能し、ランダムなポートを使用してバックエンドに接続します。これは、サーバー上のポートが枯渇するリスクを意味します。側面が存在します。バックエンドとの接続を確立する速度よりも遅い場合、ランダムなポート解放速度が発生する可能性があります。ただし、このような現象は一般的には発生せず、少なくとも弊社のNginxではこのような現象は確認されていません。なぜなら、第一に、静的リソースは CDN 上にあり、第二に、ほとんどのバックエンドは REST インターフェイスを使用してユーザー認証またはデータベース操作を提供するためです。実際、バックエンドにボトルネックがない場合、これらの操作は基本的に非常に高速です。ただし、そうは言っても、実際にバックエンドにボトルネックがあり、アーキテクチャの拡張または変更のコストが比較的高い場合、大量の同時実行に直面したときに行うべきことは、バックエンドが強制終了されないようにフローを制限することです。サーバー側の HTTP プロセスによって開かれたファイルの数が最大値に達しました
ulimit -f
が制限されているため、この値の設定が小さすぎると、HTTP 接続にも影響します。プロキシ モードで実行されている Nginx またはその他の HTTP プログラムの場合、通常、1 つの接続は 2 つのソケットを開いて 2 つのファイルを占有します (Nginx のローカル キャッシュにヒットする場合、または Nginx がデータを直接返す場合を除く)。そのため、プロキシサーバープロセスでオープンできるファイル数も多く設定する必要があります。 永続接続キープアライブまず、キープアライブは 2 つのレベルで設定でき、2 つのレベルは異なる意味を持つことを知っておく必要があります。 TCP のキープアライブは検出メカニズムです。たとえば、よく言われるハートビート情報は、相手がまだオンラインであることを示します。このハートビート情報は一定の時間間隔で送信されます。つまり、お互いの間の TCP 接続は常に開いたままにしておく必要があります。 HTTP の -alive は、TCP 接続が頻繁に確立されることを避けるために TCP 接続を再利用するメカニズムです。
したがって、TCP キープアライブと HTTP キープアライブは同じものではないことを理解する必要があります。
非永続的な接続では、各 HTTP トランザクションが完了した後に TCP 接続が切断され、次の HTTP トランザクションで TCP 接続が再確立されます。これは効率的なメカニズムであるため、HTTP/1.1 および HTTP/1.0 の拡張バージョンでは、HTTP はトランザクション終了後も TCP 接続を開いたままにしておくことができるため、後続の HTTP トランザクションはクライアントが終了するまで接続を再利用できます。サーバーは接続を積極的に閉じます。永続的な接続により、TCP 接続確立の数が減り、TCP スロー スタートによって引き起こされるトラフィック制限も最小限に抑えられます。
関連チュートリアル: HTTP ビデオ チュートリアル
この図をもう一度見てください。図の keepalive_timeout 65s
が設定されています。 http のキープアライブ機能をオンにして、タイムアウトを 65 秒に設定します。実際、もう 1 つのより重要なオプションは keepalive_requests 100;
これは、同じ TCP によって開始できる HTTP リクエストの最大数を示します。デフォルトは個別に 100 です。
キープアライブは、HTTP/1.0 のデフォルトでは使用されません。クライアントは、キープアライブを有効にするには、ヘッダー Connection: Keep-alive
を含む HTTP リクエストを送信する必要があります。サーバーがサポートしていない場合、使用されません。すべてのリクエストは通常の形式で行われます。サーバーがサポートしている場合、応答ヘッダーには Connection: Keep-alive
情報も含まれます。
Keep-alive は、HTTP/1.1 ではデフォルトで使用されます。特に指定しない限り、すべての接続は永続的です。トランザクションの終了後に接続を閉じたい場合は、HTTP 応答ヘッダーに Connection: CLose
ヘッダーが含まれている必要があります。そうでない場合、接続は常に開いたままになります。もちろん、常に開いているわけではなく、接続がアイドル状態になります。上記の Nginx 設定と同様に、アイドル状態の接続は最大 65 秒間維持でき、その後はサーバーが積極的に接続を切断します。
Linux には、TCP キープアライブ機能をオンまたはオフにするための統合スイッチがありません。システムのキープアライブ設定を確認してください。sysctl -a | grep tcp_keepalive
、次の場合変更していない場合は、Centos システムに表示されます:
net.ipv4.tcp_keepalive_intvl = 75 # 两次探测直接间隔多少秒 net.ipv4.tcp_keepalive_probes = 9 # 探测频率 net.ipv4.tcp_keepalive_time = 7200 # 表示多长时间进行一次探测,单位秒,这里也就是2小时
デフォルト設定によれば、上記の全体的な意味は、2 時間に 1 回検出することです。最初の検出が失敗した場合は、再度検出します。 75 秒後、1 回、9 回失敗すると、積極的に切断されます。
Nginx の TCP レベルでキープアライブを有効にする方法。Nginx には listen
というステートメントがあります。これは、Nginx が接続するポートを設定するために使用されるサーバー セクションのステートメントです。実際には、ソケットのプロパティを設定するために使用される他のパラメーターが続きます。次の設定を参照してください:
# 表示开启,TCP的keepalive参数使用系统默认的 listen 80 default_server so_keepalive=on; # 表示显式关闭TCP的keepalive listen 80 default_server so_keepalive=off; # 表示开启,设置30分钟探测一次,探测间隔使用系统默认设置,总共探测10次,这里的设 # 置将会覆盖上面系统默认设置 listen 80 default_server so_keepalive=30m::10;
したがって、Nginx でこの so_keepalive を設定するかどうかは、特定のシナリオによって異なります。TCP キープアライブを組み合わせないでくださいNginx では so_keepalive が有効になっておらず、HTTP リクエストでのキープアライブ機能の使用には影響しないため、HTTP キープアライブは混乱を招きます。クライアントと Nginx の間に直接、または Nginx とバックエンド サーバーの間に負荷分散デバイスがあり、応答とリクエストがこの負荷分散デバイスを通過する場合は、この so_keepalive に注意する必要があります。例えば、LVS のダイレクトルーティングモードでは応答が
LVS を経由しないため影響を受けませんが、NAT モードの場合は LVS にも応答を維持するための期間があるため注意が必要です。 TCP セッション: この期間がバックエンドがデータを返す期間よりも短い場合、LVS はクライアントがデータを受信する前に TCP 接続を切断します。
TCP 輻輳制御には、TCP スロー スタート、輻輳回避、その他のアルゴリズムを含むいくつかのアルゴリズムがあります ↩
概要IP フラグメンテーションとも呼ばれますが、すべて同じ意味です。フラグメンテーションが単にデータ リンク層によって制限される理由については、異なるデータ リンクには異なる MTU があります。イーサネットの場合は 1500 バイトです。シナリオによっては、1492 バイトになります。 FDDI の MTU は別のサイズであり、単純に IP 層を考慮すると、最大 IP データ パケットは 65535 バイトです ↩
『HTTP 権威ガイド』ページ P90 かどうかはあまり明確ではありませんこの状況はクライアントまたはサーバーに関するものであり、誤解される可能性が非常に高いため、サーバーがポート不足にならないという意味ではありません。
以上がhttp パフォーマンスに影響を与える一般的な要因を分析するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。