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複合クエリの詳細な説明

推薦する

Dockerコンテナを停止および削除できない問題の解決策

実行中のコンテナIDを見つける ドッカーps上記のコンテナの物理的な場所を見つける /var/lib...

Ubuntu 16.04 に Docker と nvidia-docker をインストールするための詳細なチュートリアル

目次DockerのインストールNvidia-docker のインストールDockerのインストール1...

jsを使用して簡単なスネークゲームを書く

この記事では、参考までに、jsで書かれたシンプルなスネークゲームの具体的なコードを紹介します。具体的...

Apache Webサーバーのインストールと設定方法

信頼性が高く、人気があり、簡単に構成できる Web サーバーである Apache で独自の Web ...

Linux 基本チュートリアル: 特別な権限 SUID、SGID、SBIT

序文Linux のファイルまたはディレクトリの権限については、共通の rwx 権限を知っておく必要が...

Nginx で 403 forbidden を解決するための完全な手順

ウェブページに403 Forbiddenと表示されるNginx (yum インストール ログは通常 ...

Vue のライフサイクルとフック関数の詳細な説明と典型的な面接の質問

目次1. Vue ライフサイクル2. フック機能2.1 4つの段階と8つの方法に分かれています。 2...

MySQL の簡単な分析 - MVCC

バージョンチェーンInnoDB エンジン テーブルでは、クラスター化インデックス レコードに 2 つ...

Vueデータ双方向バインディング実装方法

目次1. はじめに2. コードの実装2.1 目的分析2.2 実装プロセス2.2.1 エントリーコード...

Docker での WSL の構成と変更の問題について

https://docs.microsoft.com/ja-jp/windows/wsl/wsl-...

ReactRouterの実装

ReactRouterの実装ReactRouterはReactのコアコンポーネントです。主にReac...

アニメーションの再生と一時停止を制御するための CSS のヒント (非常に実用的)

今日は、CSS を使用してアニメーションの再生と一時停止を制御する非常に簡単なトリックを紹介します。...

Javascript で関数のカリー化とデカリー化を実装する方法

関数のカリー化(黒い疑問符の顔)? ? ?カレー(黒い疑問符の顔)? ? ?これは完璧な中国語翻訳で...

LinuxでPythonの組み込みバージョンを削除する手順の詳細な説明

大きな落とし穴、Linuxシステムに付属するPythonのバージョンを簡単に削除しないでください1....