まず、「LISTENING」状態の TCP ソケットには 2 つの独立したキューがあることを理解する必要があります。
これら 2 つの用語は、「reqsk_queue」、「ACK バックログ」、「listen バックログ」、または「TCP バックログ」と呼ばれることもありますが、混乱を避けるためにこの記事では上記の 2 つの用語を使用します。 SYN キュー SYN キューには、SYN パケットを受信する接続が格納されます (カーネル コード構造 struct inet_request_sock に対応)。その役割は、SYN+ACK パケットに応答し、タイムアウトするまで ACK パケットが受信されない場合は再送信することです。 Linux では、再送信回数は次のようになります。
ドキュメントにおける tcp_synack_retries の説明は次のとおりです。
SYN+ACK を送信した後、SYN キューはクライアントから送信された ACK パケット (つまり、3 ウェイ ハンドシェイクの最後のパケット) を待機します。 ACK パケットを受信すると、まず対応する SYN キューが見つかり、次に対応する SYN キュー内の関連データが一致しているかどうかがチェックされます。一致した場合、カーネルは接続に関連するデータを SYN キューから削除し、完全な接続 (カーネル コード構造 struct inet_sock に対応) を作成し、この接続を Accept キューに追加します。 キューを受け入れる Accept キューには、確立された接続、つまり上位レベルのアプリケーションによって削除されるのを待機している接続が格納されます。プロセスが accept() を呼び出すと、ソケットはキューから取り出され、上位レベルのアプリケーションに渡されます。 これは、Linux が SYN パケットを処理する方法の簡単な説明です。ちなみに、ソケットで TCP_DEFER_ACCEPT と TCP_FASTOPEN が有効になっている場合、動作方法が若干異なりますが、この記事では紹介しません。 キューサイズの制限 アプリケーションは、listen(2) システムコールを呼び出して backlog パラメータを渡すことによって、SYN キューと Accept キューの最大サイズを設定します。たとえば、次に示すように、SYN キューと Accept キューの両方の最大サイズは 1024 に設定されています。 聞く(sfd, 1024) 4.3 より前のカーネルでは、SYN キューのサイズは別の方法で計算されることに注意してください。 SYN キューの最大サイズは以前は net.ipv4.tcp_max_syn_backlog を使用して設定されていましたが、現在は使用されなくなりました。現在、net.core.somaxconn は、SYN キューと Accept キューの両方の最大サイズを表すために使用されます。私たちのサーバーでは、これを 16k に設定しています。
上記の情報を知った後、適切なキューのサイズはどれくらいなのかと疑問に思うかもしれません。適切なキューのサイズはどれくらいですか? 答えは「それは場合による」です。ほとんどの TCP サービスでは、これはそれほど重要ではありません。たとえば、Go 言語バージョン 1.11 より前では、キュー サイズを設定するメソッドはありませんでした。 ただし、キューのサイズを増やす正当な理由がいくつかあります。
ただし、バックログを大きくしすぎると、SYN キューの各スロットにメモリが必要になるため、悪影響が出る可能性があります。 SYN フラッド攻撃に遭遇した場合、これらの攻撃パケットにリソースを浪費する必要はありません。 SYN キュー内の inet_request_sock 構造体は、4.14 カーネルではそれぞれ 256 バイトのメモリを占有します。 Linux では、SYN キューの現在のステータスを表示する場合、ss コマンドを使用して SYN-RECV 状態のソケットを照会できます。たとえば、次の実行結果は、ポート 80 の SYN キューに現在 119 個の要素があり、ポート 443 の SYN キューに 78 個の要素があることを示しています。
プログラムが accept() を十分な速さで呼び出さない場合はどうなるでしょうか?このデータはSystemTapスクリプトresq.stpでも確認できます。 プログラムが accept() を十分な速さで呼び出さない場合はどうなりますか?
このような状況が発生した場合、プログラムの処理パフォーマンスが後で正常に戻り、サーバーによって破棄されたパケットをクライアントが再送信することを期待するしかありません。 カーネルのこの動作は、ほとんどのサービスで許容されます。ちなみに、グローバルパラメータ net.ipv4.tcp_abort_on_overflow を調整することでこの動作を変更できますが、このパラメータは変更しない方がよいでしょう。 nstat のカウントを表示することで、Accept キューのオーバーフローの状態を観察できます。
しかし、これは世界全体の数です。観察するのは直感的ではありません。たとえば、成長していることが観察されることもありますが、すべてのサービス プログラムは正常であるように見えます。この時点で、ss コマンドを使用して、単一のリスニング ポートの Accept キュー サイズを観察できます。
Recv-Q 列には Accept キュー内のソケットの数が表示され、Send-Q にはキューの最大サイズが表示されます。上記の例では、プログラムによって accepted() されていないソケットはないことがわかりますが、ListenDrops カウントは増加していることがわかります。 これは、プログラムが処理を永久に停止するのではなく、短時間だけ停止して新しい接続を処理しないためです。しばらくすると、プログラムは正常に戻ります。この場合、ss コマンドを使用してこの現象を観察することは難しいため、カーネルにフックして破棄された SYN パケットを出力する SystemTap スクリプトを作成しました。 $ sudo stap -v acceptq.stp 時間 (us) acceptq qmax ローカルアドレス リモートアドレス 1495634198449075 1025 1024 0.0.0.0:6443 10.0.1.92:28585 1495634198449253 1025 1024 0.0.0.0:6443 10.0.1.92:50500 1495634198450062 1025 1024 0.0.0.0:6443 10.0.1.92:65434 ... 上記の操作により、どの SYN パケットが ListenDrops の影響を受けるかを観察できます。この方法では、どのプログラムが接続を失っているかを知ることもできます。 以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
<<: HTML テーブルタグチュートリアル (32): セルの水平方向の配置属性 ALIGN
目次序文LEDトリガー探索を始めるLEDデバイス登録LEDディレクトリ類推によって理解するクラスディ...
最近のプロジェクトでフォームを作成するときに、コメント ボックスまで自動的にスクロールし、コメント ...
1.アルパインイメージをダウンロードする [root@DockerBrian ~]# docker ...
まず関数の自己呼び出しを知る必要がある関数の自己呼び出し - 自己呼び出し関数1 回限りの関数 - ...
セキュリティ上の理由から、Alibaba Cloud Server ECS にはデフォルトで独自のセ...
最近、私は「ぶどうコレクション」というプロジェクトに取り組んでいます。簡単に言うと、Budou ペー...
1. Python 3をインストールする1. 依存パッケージをインストールしますyum instal...
目次インデックスとは何ですか?左端のプレフィックス一致の原則key_lenの計算方法インデックスの最...
目次1. DOMとは何か2. 要素を選択する3. getElementById() 4. クエリセレ...
1. tomcat とは誰ですか? 2. Tomcat は何ができますか? Tomcat は Web...
この記事では、参考までに天気予報を実装するためのVueの具体的なコードを紹介します。具体的な内容は次...
目次序文考えるライブラリディレクトリの解析とダウンロード使い方ファイルの場所実際の通話質問要約する序...
マウスが画像の上を通過したときに画像のハイパーリンクを変更する方法:コードをコピーコードは次のとおり...
この記事の例では、ログインフォームを実装するためのJavaScriptの具体的なコードを参考までに共...
まとめ:以下のように、CSS で指定した行にマウスを置いたときに行全体の色を変更する方法を示します。...