Linux の TCP 接続の最大数は 65535 を超えることはできません? サーバーは何百万もの同時実行にどのように対処するのでしょうか?

まず、質問で説明されている 65535 接続は、クライアント接続数の制限を指します。

TCP アプリケーションでは、サーバーは事前に固定ポートで待機し、クライアントはアクティブに接続を開始し、3 ウェイ ハンドシェイクの後に TCP 接続を確立します。では、単一マシンの場合、同時 TCP 接続の最大数はどれくらいでしょうか?

TCP接続を識別する方法

最大接続数を決定する前に、システムが TCP 接続をどのように識別するかを見てみましょう。システムは、4 つのタプルを使用して TCP 接続を一意に識別します: {localip、localport、remoteip、remoteport}。

クライアントの最大 TCP 接続数

ポートがバインドされていない限り、クライアントが TCP 接続要求を開始するたびに、システムは通常、アイドル状態のローカル ポート (ローカル ポート) を選択するようにシステムに要求します。このポートは排他的であり、他の TCP 接続と共有することはできません。TCP ポートのデータ型は unsigned short であるため、ローカル ポートの最大数は 65536 のみであり、ポート 0 は特別な意味を持つため使用できません。このように、使用可能なポートの最大数は 65535 のみです。それらはすべてクライアントとして使用され、クライアントの TCP 接続の最大数は 65535 で、これらの接続は異なるサーバー IP に接続できます。

サーバーの TCP 接続の最大数

サーバーは通常、特定のローカル ポートをリッスンし、クライアントからの接続要求を待ちます。アドレスの再利用 (Unix SO_REUSEADDR オプション) に関係なく、サーバー側に複数の IP がある場合でも、ローカル リスニング ポートは排他的であるため、サーバー側にはリモート IP (つまり clientip) とリモート ポート (clientip) のみが存在します。 tcp 接続 (4 タプル、ターミナル ポート) は可変であるため、最大 tcp 接続数はクライアント ip 数 × クライアント ポート数になります。IPV4 の場合、ip アドレスの分類などの要因に関係なく、最大 tcp 接続数は約2 の 32 乗(ip 番号)× 2 の 16 乗(ポート数)、つまり、サーバー側単一マシンの最大 tcp 接続数は約 2 の 48 乗です。

実際の TCP 接続数

上記は 1 台のマシンに対する理論上の最大接続数ですが、実際の環境では、マシンのリソースやオペレーティング システム、特にサーバー側で制限されるため、最大同時 TCP 接続数は理論上の上限から大きく外れます。UNIX/Linux での接続数を制限する主な要因は、メモリと許可されるファイル記述子の数 (各 TCP 接続は一定量のメモリを占有し、各ソケットはファイル記述子です) であり、通常 1024 未満のポートは予約されます。ポート。

したがって、サーバー側でメモリを増やし、ファイル記述子の最大数などのパラメータを変更することで、単一マシン上の最大同時 TCP 接続数が 100,000、さらには数百万を超えても問題ありません。

これは明らかに考え方の誤解であり、65535 は使用可能なポートの総数を指しており、サーバーが同時に 65535 個の同時接続しか受け入れられないという意味ではありません。

例えば:

TCP のポート 80 にバインドされた Web サイトを作成したため、この Web サイトにアクセスするすべてのユーザーは、他のポートではなく、サーバーのポート 80 を介してアクセスします。ポートが再利用できることがわかります。画像Linux サーバーがポート 80 でのみサービスをリッスンする場合でも、100,000 または 100 万人のユーザーがサーバーに接続できます。Linux システムでは接続数に制限はありませんが、サーバーが多数の接続に耐えられるかどうかは、サーバーのハードウェア構成、ソフトウェア アーキテクチャ、最適化によって決まります。

01

2 つのプロセスが通信するための最も基本的な前提条件は、プロセスを一意に識別できることであることがわかっています。ローカル プロセス通信では、PID を使用してプロセスを一意に識別できますが、PID はローカルでのみ一意であり、ネットワーク内の 2 つのプロセス間で PID の競合が発生する可能性が高くなります。

このとき、IPアドレスはホストを一意に識別でき、TCP層のプロトコルとポート番号はホストのプロセスを一意に識別できるので、IPアドレス+プロトコル+ポート番号という別の方法を考える必要があります。ネットワーク内のプロセスを一意に識別するために使用できます。

ネットワーク内のプロセスを一意に識別できるようになると、ソケットを使用して通信できるようになります。ソケット (ソケット) は、アプリケーション層とトランスポート層の間にある抽象化層であり、TCP/IP 層の複雑な操作をいくつかの単純なインターフェイスに抽象化し、アプリケーション層がネットワーク内で通信するための実現されたプロセスを呼び出すことができます。画像ソケットは Unix に由来し、「オープン-読み取り/書き込み-クローズ」モードの実装です。サーバーとクライアントはそれぞれ「ファイル」を維持します。接続が確立されて開かれた後、コンテンツを独自のファイルに書き込むことができます。相手に読み取ってもらうか、相手の内容を読み取って、通信が終了したらファイルを閉じます。

02

接続を判断できるのは次の 4 つのことだけです。

  1. サーバーのIP

  2. サーバーのポート

  3. クライアントのIP

  4. クライアントポート

サーバーの IP とポートは変更されず、クライアントの IP とポートが互いに異なっていれば、接続番号を決定できます。画像ソケットは複数の接続を確立でき、TCP 接続は 4 つの要素 (source_ip、source_port、destination_ip、destination_port)、つまり 4 つの要素 (送信元 IP、送信元ポート、宛先 IP、宛先ポート) の組み合わせとしてマークされます。4 つの要素の組み合わせのうち 1 つの要素が異なれば、異なる接続を区別できます。

例えば:

-> ホストの IP アドレスは 1.1.1.1 で、ポート 8080 でリッスンしています。

→2.2.2.2から接続要求を送信する場合、ポートは5555になります。この接続の 4 倍は (1.1.1.1, 8080, 2.2.2.2, 5555) です。

-> このとき、2.2.2.2 は 2 番目の接続要求を送信します。ポートは 6666 です。新しい接続の 4 倍は (1.1.1.1, 8080, 2.2.2.2, 6666) です。

次に、ホストのポート 8080 で 2 つの接続が確立されます。

-> (2.2.2.2) からの 3 番目の接続リクエスト、ポートは 5555 (または 6666) です。3 番目の接続の要求は、上の 2 つの接続と区別する方法がないため、確立できません。

同様に、同じポート番号と IP アドレスでTCP ソケットと UDP ソケットをバインドできます。

ポート番号は同じですが、プロトコルが異なるため、ポートは完全に独立しています。

TCP/UDP は通常、5 つのタプルを使用して接続を見つけます。

ソース IP、ソース ポート、宛先 IP、宛先ポート、プロトコル タイプ

つまり、(送信元IP、送信元ポート、宛先IP、宛先ポート、プロトコル番号)

要約すると、サーバーの同時接続数は TCP の 65535 ポートによって決まりません。サーバーが同時に処理できる同時実行数は、帯域幅、ハードウェア、プログラム設計などのさまざまな要因によって決まります。

したがって、淘宝網、テンセント、頭条、百度、新浪、ビープビープなどが、サーバー クラスターを使用しているため、1 秒あたり数億件の同時アクセスに耐えられる理由も理解できます。サーバクラスタは全国の大きな計算機室に分散されており、トラフィックが少ないときは一部のサーバを停止し、トラフィックが多いときは継続的に新しいサーバを立ち上げます。


上記の個人的な見解については、批判や修正を歓迎します。

あなたの質問には論理的な間違いがいくつかあります。一つずつ説明させてください。

画像

最初の間違いは、TCP 接続の数が Linux とは関係がないことです。Windows、Linuxを問わず、TCP/IPを使用している限り、1つのIPアドレスから同一のインターネットサービスに接続されるTCPコネクションの数は65535を超えることはなく、通常の状況でも65535を超えると考えられます。 40,000 を超えてはなりません (ここでは同じインターネット サービス、つまり同じ宛先アドレスとポートを指します)。

その理由は、TCP/IP では、TCP ポートの長さが 16 ビット (バイナリ) であるとプロトコルで規定されているため、TCP 接続は送信元 IP アドレスの 1 つの TCP ポートを消費し、TCP ポートの数は 65535 個になるためです。 )、10進数では1~65535となります。

画像

これは、コンピュータが Web サイトにアクセスしたい場合、コンピュータがこの Web サイトとの間に 65535 の接続しか確立できず、1 つの接続で 1 つの TCP ポートを消費することも意味します。もちろん、これは理想的な状況であり、実際には、多くのポートがいくつかの既知のプロトコルによって占有または予約されています。たとえば、ポート 80 は HTTP に属しているため、使用できるポートの数は一般的に考えられています。約40,000です。

2 番目の間違いは、TCP ポートの数がサーバーとは関係がないことです。ここで言及されている 40,000 の TCP ポートは、Web サイトへのアクセスに使用するパーソナル コンピュータが使用する送信元ポートと、Web サイトのポートである宛先ポートを指すため、使用される TCP ポートは同じです。 23ポート。これは、40,000 の接続すべてがこの Web サイトのポート 23 に接続され、別のユーザーが 40,000 の接続を使用してサーバーのポート 23 に接続できることを意味します。

画像

したがって、100 万の同時接続がある場合、1 人のユーザーによる 40,000 回の訪問の場合、同時接続ユーザーは 25 人であると大まかに見積もることができます。もちろん、実際の使用では、同じ Web サイトにアクセスするために PC が 40,000 接続することはありませんが、4 接続の PC を使用して Web サイトにアクセスすると仮定すると、同時接続ユーザー数が 100 万人ということは、ユーザー数は 250,000 人になります。

最後に、あなたの質問に答えるために、サーバーは何百万もの TCP 接続をどのようにサポートしているのでしょうか? これはサーバーのリソースに関連しています。実際には、単一のサーバーがサポートする TCP 接続の数は実際には限られています。単一のサーバーがサポートする TCP 接続は理論値に達することはできません。サービス接続が多すぎると、CPU がメモリをサポートできなくなるため、各サーバーは仕様上の制限により、ハードウェアのパフォーマンスが強化されるほど、サーバーがサポートする TCP 接続の数が増加します。

ただし、Web サイトには複数のサーバー (クラスター サーバー) を配置することができ、サーバーのサイズが大きくなるほど、サポートされるアクセス機能が強化されるため、これは問題になりません。

画像

たとえば、アリババはダブル11をどうやって生き延びたのでしょうか? Alibaba Cloud は北京、上海、広州、深センなどにサーバーを設置しており、各場所のサーバーはエラスティック クラスターであり、これらのサーバーはタオバオ上のデータの一貫性を確保するためにリアルタイムで同期されています。したがって、ダブル 11 に淘宝網にアクセスする場合、北京のサーバーにアクセスする人もいれば、上海のサーバーにアクセスする人もいます。このように、分散サービスの分散ストレージを通じて、Web サイトが対応できる同時実行性は当然非常に大きくなります。

家主は 65535 (ポートの数) と接続の数は別のことであると理解していますが、これは間違っています。具体的な理由については、多くの同業者がすでに明確に説明しているので、改めて説明することはしません。

元のポスターの後半、つまりサーバーは何百万もの同時実行をどのようにサポートしているのかについて具体的に答えてみましょう。

以下で説明する視点は、システムアーキテクチャの最適化によるシステムの負荷容量の向上、つまりシステムの同時実行性の向上です。

1. 高同時実行性とは

画像

高い同時実行性はインターネット システムが直面する一般的な問題であり、システム アーキテクチャで考慮される重要な要素の 1 つでもあります。

[同時実行性と負荷] は 2 つの相対的な言葉です。

高い同時実行性を実現するには、システムの負荷容量を増やす必要があります。システムの負荷容量が大きい場合、自然に大量の同時リクエストを処理できます。

したがって、高い同時実行性を実現するには、システムの負荷容量を向上させることが重要です。

一般に、システム負荷容量の評価パラメータには、応答時間、スループット、1 秒あたりのリクエストの QPS、および同時ユーザー数が含まれます。

  • 応答時間: システムがリクエストに応答するまでにかかる時間。たとえば、システムが HTTP リクエストを処理するのに 200 ミリ秒かかり、この 200 ミリ秒がシステムの応答時間になります。
  • スループット: 単位時間当たりに処理されるリクエストの数。
  • QPS: 1 秒あたりの応答リクエストの数。スループットの概念に似ています。
  • 同時ユーザー数: システム機能を同時に使用するユーザーの数。

2. 同時処理能力(同時数)を向上させる方法

以下の内容では、[帯域幅]と[ハードウェア構成]の2つの要素は考慮されていないことに注意してください。

明らかに、高帯域幅と高ハードウェア構成により、強力なシステム負荷容量と処理できる同時ユーザー数が増加します。

では、同時処理能力を向上させるにはどうすればよいでしょうか?

答えは、システム アーキテクチャを最適化することで同時処理能力を向上させることです。

また、システム アーキテクチャの設計は、技術レベルだけでなくビジネス レベルも関わる複雑なプロセスです。

3. 事業分割による同時処理能力の向上(マイクロサービスアーキテクチャ)

画像

システムを複数のサブシステムに分割し、各サブシステムが個別のサービスを担当します。これは、多くの場合 [サービス ガバナンス] と呼ばれます。

複数のサブシステムに分割した後、各サブシステム (サービス) は独立して実行され、各サービスは REST/RPC を通じて呼び出され、ユーザーはこれらのサービス インターフェイスを直接呼び出すこともできます。

このような設計により大小が決まり、この種のアーキテクチャは [マイクロサービス アーキテクチャ] とも呼ばれます。

例:モールシステムでは、「注文サービス」「ユーザーサービス」「商品サービス」など複数のサービスインターフェースに分けることができます。

4. 水平拡張による同時処理能力の向上

この部分については別途説明します。

1. フロントエンド部

画像

nginx リバース プロキシ ソフトウェアを使用して同時処理を増やす

Nginx は水平方向にスケーリングします: DNS ポーリングなど。

2. アプリケーションサーバー部

画像

Java の一般的なアプリケーション サーバーである Tomcat を例に挙げると、クラスタリングと負荷分散を実現できます。クラスタ構成が成功した後は、「サーバプール」を用意したことと同じになり、処理能力を高めたい場合は、「プール」にアプリケーションサーバを追加し続けるだけで済みます。さらに、クラスターはシステムの高可用性も実現します。

3. データベースレベル

サブデータベースとテーブルの共通化、読み取りと書き込みの分離は、データベースへの負荷を解決する方法の 1 つです。

データベースのボトルネックは、システム運用において最初に発生し、最も頻繁に発生する問題の 1 つです。

よくある問題は、ディスク IO が高く、処理が遅くなるということです。

先ほど説明した方法でこの問題を解決できます。

一般的なテーブル分割の原則は、範囲によるものとハッシュ値によるものです。

4. キャッシュレベル

画像

現在、システムへのキャッシュの追加は必須のオプションです。

キャッシュを追加する主な目的は、ディスク IO を削減することです。

ページ コンテンツ (HTML、CSS、画像) のキャッシュ、アプリケーション サーバー内のデータ オブジェクトのキャッシュなど、キャッシュできるコンテンツは数多くあります。

多値キャッシュの設計により、データの高速取得とリクエストへの高速応答を実現します。

分散アーキテクチャでは、分散キャッシュの更新の一貫性にも注意を払う必要があります。(詳細はありません)

5つ目、ついに

実際、多くのシステムの同時実行数は 100 万未満であり、同時実行数を備えているのは、淘宝網などの少数のトップ Web サイトだけです。

しかし、私たちが百万レベルの同時実行アーキテクチャを解決する方法を研究する理由は、そこから[システム アーキテクチャの進化プロセス]を学び、習得するためです。

システム アーキテクチャ設計の原則は、「適切なものが最善である」です。百万レベルの構造を最初から満たすことは、コストの増加と資源の無駄を引き起こすため、不可能です。

したがって、システム アーキテクチャは進化するものであることを理解する必要があります。

対象者には概念的な誤解があり、TCP ポート番号 65535 の上限を TCP 接続数の上限と誤って解釈し、Linux では 65,535 を超える同時タスクを達成できないと信じています。数値と TCP 接続の数には違いがありますが、1 対 1 の関係ではありません。

65,535 はどこから来て、何をしたのでしょうか?

画像

この問題をうまく説明するには、まず 65,535 の意味を明確にする必要があります。Linux システムでは、2 台のマシンが通信したい場合、相互に TCP 接続を確立する必要があります。2 つのマシンがお互いを認識できるようにするために、Linux システムは 4 つの値を使用して TCP 接続を一意に識別します: {local ip , ローカル ポート, リモート ip , リモート ポート}、つまり、ローカル IP、ローカル ポート、リモート IP、およびリモート ポート。IP とポートは、コミュニティの住所と番地に相当します。これらの情報を使用してのみ、2 者間で情報を共有できます。コミュニケーションの中でお互いを認識します。Linux システムでは、ポート番号を表す変数 (port) が 16 ビットを占有するため、ポート番号の数は最大でも 2 の 16 乗、つまり 65,536 個となります。また、ポート 0 には特別な意味があり、は使用されないため、各サーバーでは最大 65,535 個のポートが使用可能になります。したがって、65,535 は Linux システムでサポートされる TCP ポート番号の数を表し、TCP が接続を確立するときに使用されます。

TCP はどのように接続を確立しますか?また、ポート番号との関係は何ですか?

画像

Linux サーバーが対話する場合、通常、クライアントまたはサーバーという 2 つの ID があります。典型的な対話シナリオは次のとおりです。

(1) サーバーはアクティブにリスニングソケットを作成し、外部サービスポートをバインドしてからリスニングを開始します。

(2) クライアントがサーバーと通信したい場合、サーバーのポート port への接続を開始します。

(3) サーバーはクライアントのリクエストを受け入れ、新しいソケットを生成します。

(4) サーバーとクライアントは新しいソケットで通信します

ポート port は主にサーバーとクライアント間の「ハンドシェイク認識」プロセスで使用されることがわかります。お互いが認識されると、通信用のソケットが生成されます。この時点では、ポートは必要なくなります。他のソケット通信に使用できるため、TCP 接続の数が TCP ポート番号の数 65,535 より大きくなる可能性があることは明らかです。

Linux サーバーがクライアントまたはサーバーとしてのみ使用されるという 2 つの極端なシナリオを考えてみましょう。

(1) Linux サーバーはクライアントとしてのみ機能します

このとき、TCP リクエストが開始されるたびに、システムは使用する空間のローカル ポートを指定しますが、これは排他的であり、他の TCP 接続に奪われないため、最大 65535 の接続が可能です。を確立することができ、各接続は異なるサーバーと対話するために接続されます。この手のシナリオはまさにトピ主さんのおっしゃる通りですが、条件が過酷すぎて確率が低い事象なので、むしろ理論上はあり得ることであり、現実の環境ではまず発生しません。

(2) Linuxサーバーはサーバーとしてのみ使用されます

このシナリオでは、サーバーはローカル ポート port を固定的にリッスンし、クライアントがそれに対するリクエストを開始するのを待ちます。簡単に計算するために、サーバーの IP とポートは多対 1 であると仮定し、TCP クアドルプルのリモート IP とリモート ポートは可変であるため、サポートされる TCP の最大数は 2 から 2 までになります。 32 乗 (IP アドレスは 32 ビット) に 2 の 16 乗 (ポートは 16 ビット) を乗算すると、2 の 48 乗に等しくなります。

実際に単一の Linux サーバーでサポートされる TCP 接続の数

これまでの分析により、実際のシナリオでは、ポートの多重化により、サーバーが同時にサポートできる TCP 接続の数が 65,535 と 1 対 1 に対応しないことがわかりました。 TCP 接続の数に実際に影響を与えるサーバー TCP 接続が作成されるたびにソケット ハンドルが作成され、各ソケット ハンドルが一部を占有するため、単一のプロセスによって同時に開くことができるメモリとファイルの数システム メモリが使い果たされると、許可される同時 TCP 接続の数も上限に達します。一般に、サーバーのメモリを増やしたり、ファイル記述子の最大数を変更したりすることにより、単一サーバーで 100,000 以上の TCP 同時実行をサポートできます。

画像

もちろん、実際の商用シナリオでは、単一のサーバーが分散クラスターに組み込まれ、さまざまなユーザーのリクエストが負荷分散アルゴリズムを通じて最もアイドル状態のサーバーに動的にディスパッチされます。サーバーの平均メモリ使用量が超過した場合、警告ラインが 80% の場合、サービスを確保するために電流制限またはクラスターの拡張を速やかに実施します。サーバーのメモリが枯渇するような状況は発生しないため、事故とみなされます。

つまり、65,535 は Linux システムで使用できるポート数の上限にすぎず、ポート数と TCP 接続数は厳密に 1 対 1 に対応するわけではありません。サーバーによる同時 TCP 接続の数は、主にサーバーのメモリと、単一プロセスが同時に開くことを可能にするファイルに関連しています。ポートの多重化とサーバー パラメータの調整によって、サーバーがサポートする同時 TCP 接続の数が決まります。単一サーバーは 65,535 を超える場合があります。

転載元: https://blog.csdn.net/daocaokafei/article/details/115410761

おすすめ

転載: blog.csdn.net/qq_43842093/article/details/132642193