TCPパフォーマンスチューニングの実装原理とプロセス分析

TCPパフォーマンスチューニングの実装原理とプロセス分析

3ウェイハンドシェイクフェーズ

クライアントSYNパケットの再試行回数

sysctl -w net.ipv4.tcp_syn_retries=6

関連の紹介

最初の再試行は 1 秒後に行われ、その後 2、4、8、16、32 秒の 6 回の再試行が 2 倍の間隔で行われます。最後の再試行は 64 秒間待機します。それでも ACK が返されない場合は、3 ウェイ ハンドシェイクが終了します。したがって、合計時間は1+2+4+8+16+32+64=127秒となり、2分を超えます。

サーバー半接続プールのサイズ

sysctl -w net.ipv4.tcp_max_syn_backlog=16384

サーバーのセミ接続プールがいっぱいになった後にsyncookieメカニズムを有効にするかどうか

sysctl -w net.ipv4.tcp_syncookies=1

関連の紹介

SYN 半接続キューがいっぱいになると、デフォルトでは接続が切断されます。これは当てはまりません。syncookies 機能をオンにすると、SYN キューを使用せずに接続を正常に確立できます。

Syncookies は次のように動作します。サーバーは現在の状態に基づいて値を計算し、送信する SYN+ACK メッセージにその値を入れます。クライアントが ACK メッセージを返すと、検証のために値が取り出されます。それが正当であれば、下の図に示すように、接続が正常に確立されたとみなされます。

  • 0 は、この機能をオフにすることを意味します。
  • 2 は機能を無条件に有効にすることを意味します。
  • 1 は、SYN セミ接続キューがいっぱいの場合にのみ有効になることを意味します。

注: syncookie は SYN フラッド攻撃 (攻撃者が悪意を持って大量の SYN メッセージを作成し、それをサーバーに送信して、SYN 半接続キューをオーバーフローさせ、通常のクライアント接続を確立できなくなる攻撃) に対処するためにのみ使用されるため、この方法で確立された接続では多くの TCP 機能を使用できません。したがって、tcp_syncookies を 1 に設定し、キューがいっぱいになった場合にのみ有効にする必要があります。

サーバーのSYN+ACKパケットの再試行回数

net.ipv4.tcp_synack_retries=5

関連の紹介

tcp_synack_retries のデフォルトの再試行回数は 5 回で、これはクライアントが SYN を再送信するのと似ています。再試行は 1、2、4、8、16 秒で行われます。最後の再試行の後、32 秒間待機します。それでも ACK が受信されない場合は、接続が閉じられるため、合計 63 秒間待機する必要があります。

サーバーのフル接続キューのサイズ

min(backlog, /proc/sys/net/core/somaxconn) に依存します。Linux カーネル バージョン 2.2 以降では、listen 関数の backlog パラメータで accept キューのサイズを設定できます。

さらに、バックログ パラメータは、Linux システム レベルのキューの長さの上限によっても制限されます。もちろん、この上限しきい値は somaxconn パラメータによって変更することもできます。somaxconn はカーネル パラメータであり、デフォルト値は 128 です。

sysctl -w ネット.コア.somaxconn=32768

4つの波の段階

次に、最初に接続を閉じる側をアクティブ パーティ、後で接続を閉じる側をパッシブ パーティと呼びます。

4つの波のプロセス:

実際、4 つの波には FIN と ACK の 2 種類のメッセージのみが含まれます。 FIN は Finish の略で、接続の終了を意味します。FIN メッセージを送信する人は、これ以上データを送信せず、この方向の伝送チャネルを閉じることを意味します。 ACK は Acknowledge の略で、送信チャネルが閉じられたことを相手に通知するために使用されます。アクティブ側が接続を閉じると、FIN メッセージが送信され、アクティブ側の接続状態が ESTABLISHED から FIN_WAIT1 に変わります。受動側が FIN メッセージを受信すると、カーネルは自動的に ACK メッセージで応答し、接続状態が ESTABLISHED から CLOSE_WAIT に変わります。名前が示すように、プロセスが close 関数を呼び出して接続を閉じるのを待機しています。アクティブ側がこの ACK メッセージを受信すると、接続状態が FIN_WAIT1 から FIN_WAIT2 に変わり、アクティブ側の送信チャネルが閉じられます。次に、受動側の送信チャネルがどのように閉じられるかを見てみましょう。受動側が CLOSE_WAIT 状態に入ると、プロセスの読み取り関数は 0 を返すため、開発者はターゲットを絞ってクローズ関数を呼び出し、カーネルが FIN メッセージを送信するようにトリガーします。このとき、受動側の接続状態は LAST_ACK になります。アクティブ側がこの FIN メッセージを受信すると、カーネルは自動的に ACK を返信し、接続ステータスは FIN_WAIT2 から TIME_WAIT に変わります。Linux システムでは、TIME_WAIT 状態の接続は約 1 分後に完全に閉じられます。受動側が ACK メッセージを受信すると、接続は閉じられます。

アクティブサイド最適化

ACK、FINパケットの再送待ち時間

アクティブなパーティが FIN メッセージを送信すると、接続は FIN_WAIT1 状態になりますが、通常は数十ミリ秒以内に FIN_WAIT2 に変換されます。相手から返される ACK が長時間受信されない場合にのみ、netstat コマンドを使用して FIN_WAIT1 状態を観察できます。この時点で、カーネルは FIN メッセージを定期的に再送信します。再送信の回数は tcp_orphan_retries パラメータによって制御されます (orphan は孤立を意味しますが、このパラメータは孤立した接続に対してのみ有効ではなく、実際には FIN_WAIT1 状態のすべての接続に対して有効であることに注意してください)。デフォルト値は 0、具体的には 8 回です。

net.ipv4.tcp_orphan_retries = 0

孤立した接続の数

net.ipv4.tcp_max_orphans = 16384

関連の紹介

tcp_max_orphans は孤立接続の最大数を定義します。プロセスが close 関数を呼び出して接続を閉じると、接続は FIN_WAIT1 状態になります。この接続はプロセスとは何の関係もなく、孤立した接続になります。孤立した接続が多すぎてシステム リソースが長時間占有されるのを防ぐために、Linux システムでは tcp_max_orphans パラメータが用意されています。孤立接続の数がこれより多い場合、新しく追加された孤立接続は 4 つの波を通過せず、RST リセット メッセージを直接送信して強制的に閉じられます。

孤立接続の定義: プロセスが close を呼び出すことによって閉じられた接続は、孤立接続と呼ばれます。また、shutdown 関数でも接続を閉じることができます。どちらも相手に FIN メッセージを送信します (FIN を送信するには、SHUT_WR または SHUT_RDWR にシャットダウン パラメータを渡す必要があります)。違いは、close 呼び出し後、相手が半クローズ状態で送信したデータがアクティブな相手に届いても、プロセスはそれを受信できないことです。 netstat -p コマンドを使用すると、接続に対応するプロセス名が空であることがわかります (プロセスとは何の関係もありません)。シャットダウン関数が呼び出された後、接続が FIN_WAIT1 または FIN_WAIT2 状態になったとしても、孤立した接続ではなく、プロセスは引き続きデータを受信できます。

FINの待ち時間

net.ipv4.tcp_fin_timeout = 60

関連の紹介

接続が ACK を受信して​​ FIN_WAIT2 状態に入ると、アクティブなパーティの送信チャネルが閉じられたことを意味します。次に、相手側が FIN メッセージを送信するのを待ち、相手側の送信チャネルを閉じます。このとき、シャットダウン機能を使用して接続を閉じると、接続は FIN_WAIT2 状態のままになることがあります。ただし、close 関数によって閉じられた孤立した接続の場合、この状態は長く続くことはできず、tcp_fin_timeout は接続がこの状態で続く時間を制御します。

TIME_WAIT関連のパラメータ

関連の紹介

TIME_WAIT は、アクティブ パーティの 4 つの波の最後の状態です。アクティブ側は、パッシブ側からFINメッセージを受信すると、ACKを返信し、相手側の送信チャネルが閉じられたことを確認します。その後、接続はTIME_WAIT状態に入り、60秒待機した後に閉じられます。

TIME_WAIT 状態の最大接続数

TIME_WAIT 接続の数がこのパラメータを超えると、新しく閉じられた接続は TIME_WAIT を経由せず、直接閉じられます。

net.ipv4.tcp_max_tw_buckets = 5000

TIME_WAIT状態のポートを再利用するかどうか

TIME_WAIT 状態のポートを再利用するには、サーバーがアップストリーム サーバーへの接続をアクティブに開始する場合、tcp_tw_reuse パラメーターを 1 に設定します。これにより、クライアントとしての新しい接続が安全な条件下で TIME_WAIT 状態のポートを使用できるようになります。

net.ipv4.tcp_tw_reuse = 1

もちろん、tcp_tw_reuse を有効にするには、timestamps パラメータを 1 に設定する必要があります。これは、安全な再利用の前提条件を満たしています (相手側でも tcp_timestamps をオンにする必要があります)。

net.ipv4.tcp_timestamps = 1

Linux の古いバージョンでは、tcp_tw_recycle パラメータも提供されていますが、これは TIME_WAIT 状態が 60 秒間存在する必要がないため、データの混乱を招く可能性があります。これを 1 に設定することはお勧めしません。

net.ipv4.tcp_tw_recycle = 0

そのため、Linux バージョン 4.12 以降では、このパラメータは直接キャンセルされました。

その他の構成

システムによって開くことが許可されているポート範囲

sysctl -w net.ipv4.ip_local_port_range=1024 65000

システムがグローバルに割り当てることができるファイルハンドルの最大数

sysctl -w fs.file-max=2097152

sysctl -w fs.nr_open=2097152

エコー 2097152 > /proc/sys/fs/nr_open

現在のセッションまたはプロセスで許可されているオープンファイルハンドルの数

ulimit -n 1048576

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • Python に基づいて TCP 3 ウェイ ハンドシェイク接続をシミュレートし、データを送信する
  • TCP/IPプロトコルにおける3ウェイハンドシェイクと4ウェイウェーブの原理とプロセスの分析
  • TCPの3ウェイハンドシェイクと4ウェイウェーブの詳細な紹介
  • Wireshark の基本的な紹介と TCP 3 ウェイ ハンドシェイクの学習
  • TCP 3ウェイハンドシェイクと原理
  • TCPソケットSYNキューとAcceptキューの差異分析
  • Java での TCP プロトコル ソケット ネットワーク プログラミングに基づくファイル転送の実装
  • JavaはTCPプロトコルに基づいてファイルアップロードを実装します
  • TCP 3 回目のハンドシェイク データ転送プロセス図

<<:  マークアップ言語 -

>>:  MySQL複合クエリの詳細な説明

推薦する

MySQL 重複インデックスと冗長インデックスの例の分析

この記事では、例を使用して MySQL の重複インデックスと冗長インデックスについて説明します。ご参...

Ubuntu の仮想環境に Django をインストールする方法

Ubuntu コマンドライン ウィンドウで次の操作を実行します。 1. 仮想環境をインストールする...

入力のid属性とname属性の違いの例

長い間ウェブサイトを作ってきましたが、入力時のnameとidの違いがまだわかりません。最近jQuer...

良いデザインについて

<br />「良いデザインとは何か」と答える 1 万人に対して、少なくとも 1 万 1 ...

CocosCreator で http と WebSocket を使用する方法

目次1. HTTPGET 2. HTTP POSTウェブソケット4. Egretのhttpとwebs...

MySQL でのトランザクションの使用方法

基礎トランザクションは、SQL ステートメントのグループに対するアトミック操作です。つまり、グループ...

Windows オペレーティング システムでポートの使用状況を照会およびクリアするプログラム

Windowsオペレーティングシステムでは、ポートの占有状況を照会し、ポートの占有状況をクリアするプ...

キャンバス操作プラグイン fabric.js の使い方を詳しく解説

Fabric.js は非常に便利なキャンバス操作プラグインです。ここでは、日常のプロジェクトで使用さ...

ウェブページの幅を携帯電話の画面(ビューポート)の幅に自動的に適応させる実装コード

一般的な書き方は次のとおりです。 XML/HTML コードコンテンツをクリップボードにコピー<...

MySQL スロークエリ: スロークエリを有効にする

1. スロークエリの用途は何ですか? long_query_time を超えて実行されるすべての S...

MySQLビューの原理と使用法の詳細な説明

この記事では、例を使用して MySQL ビューの原理と使用方法を説明します。ご参考までに、詳細は以下...

JavaScript で Baidu Maps API にアクセスする方法と手順

目次1. Baidu Map API アクセス2. HTML で Baidu Map API を使用...

mysql トリガーの作成と使用例

目次トリガーとは何かトリガーを作成するMySQL 作成構文のキーワードの説明: 1. MySQL ト...

NexusはAPIを使用して操作します

Nexus は RestApi を提供していますが、一部の API はまだ Groovy と組み合わ...

MySQL の左結合操作における on 条件と where 条件の違いの紹介

優先度両方のケースで同じ条件を設定すると、異なる結果セットが生成される可能性があるのは、優先順位のた...