Heim  >  Artikel  >  Betrieb und Instandhaltung  >  Welche Faktoren beeinflussen die Anzahl der TCP-Verbindungen im Linux-System?

Welche Faktoren beeinflussen die Anzahl der TCP-Verbindungen im Linux-System?

青灯夜游
青灯夜游Original
2022-11-07 18:47:382163Durchsuche

Die Hauptfaktoren, die die Anzahl der TCP-Verbindungen in einem Linux-System beeinflussen, sind der Speicher und die Anzahl der zulässigen Dateideskriptoren, da jede TCP-Verbindung eine bestimmte Menge an Speicher belegt und jeder Socket ein Dateideskriptor ist 1024 normalerweise Ein reservierter Port.

Welche Faktoren beeinflussen die Anzahl der TCP-Verbindungen im Linux-System?

Die Betriebsumgebung dieses Tutorials: Linux7.3-System, Dell G3-Computer.

In TCP-Anwendungen lauscht der Server im Voraus an einem festen Port, der Client initiiert aktiv eine Verbindung und die TCP-Verbindung wird nach einem Drei-Wege-Handshake hergestellt. Wie viele gleichzeitige TCP-Verbindungen kann eine einzelne Maschine maximal haben?

So identifizieren Sie eine TCP-Verbindung

Bevor wir die maximale Anzahl von Verbindungen ermitteln, werfen wir zunächst einen Blick darauf, wie das System eine TCP-Verbindung identifiziert. Das System verwendet ein 4-Tupel, um eine TCP-Verbindung eindeutig zu identifizieren: {localip, localport,remoteip,remoteport}.

Maximale Anzahl von TCP-Verbindungen für den Client

Jedes Mal, wenn ein Client eine TCP-Verbindungsanforderung initiiert, wählt das System normalerweise einen freien lokalen Port (lokaler Port) aus Kann nicht mit anderen TCP-Verbindungen kombiniert werden, die gemeinsam genutzt werden. Der Datentyp des TCP-Ports ist unsigned short, daher beträgt die maximale Anzahl lokaler Ports nur 65536. Port 0 hat eine besondere Bedeutung und kann nicht verwendet werden. Daher sind maximal 65535 Ports verfügbar als Clients verwendet werden, beträgt die maximale Anzahl an TCP-Verbindungen für einen Client 65535, diese Verbindungen können mit unterschiedlichen Server-IPs verbunden sein.

Maximale Anzahl von TCP-Verbindungen für den Server

Der Server ist normalerweise so festgelegt, dass er an einem lokalen Port lauscht und auf die Verbindungsanfrage des Clients wartet. Ohne Berücksichtigung der Wiederverwendung von Adressen (die SO_REUSEADDR-Option von Unix) ist der lokale Überwachungsport exklusiv, selbst wenn auf der Serverseite mehrere IPs vorhanden sind. Daher gibt es nur RemoteIP (dh ClientIP) und Remote-Port (Client). 4-Tupel der serverseitigen TCP-Verbindung) ist variabel, daher ist die maximale TCP-Verbindung die Anzahl der Client-IPs × die Anzahl der Client-Ports. Bei IPV4 ist die maximale Anzahl unabhängig von Faktoren wie der IP-Adressklassifizierung TCP-Verbindungen betragen ungefähr 2 hoch 32 (Anzahl der IPs) × 2 hoch 16 (Anzahl der Ports), d. h. die maximale Anzahl von TCP-Verbindungen auf einer einzelnen Maschine auf der Serverseite beträgt ungefähr 2 hoch 48 .

Die tatsächliche Anzahl der TCP-Verbindungen

Das Obige ist die theoretische maximale Anzahl von Verbindungen für eine einzelne Maschine, die in der tatsächlichen Umgebung durch Maschinenressourcen, Betriebssysteme usw., insbesondere auf der Serverseite, begrenzt ist , dessen maximale Anzahl gleichzeitiger TCP-Verbindungen bei weitem nicht die theoretische Obergrenze erreicht. Die Hauptfaktoren, die die Anzahl der Verbindungen unter Unix/Linux begrenzen, sind der Speicher und die Anzahl der zulässigen Dateideskriptoren (jede TCP-Verbindung belegt eine bestimmte Menge an Speicher und jeder Socket ist ein Dateideskriptor). reserviert. Unter der standardmäßigen 2.6-Kernelkonfiguration belegt jeder Socket nach dem Testen zwischen 15 und 20 KB Speicher.

Auf der Serverseite ist es also kein Problem, durch Erhöhung des Speichers und Änderung von Parametern wie der maximalen Anzahl von Dateideskriptoren die maximale Anzahl gleichzeitiger TCP-Verbindungen auf einem einzelnen Computer auf mehr als 100.000 oder sogar Millionen zu erhöhen.

Dies ist offensichtlich ein Missverständnis. 65535 bezieht sich auf die Gesamtzahl der verfügbaren Ports. Dies bedeutet nicht, dass der Server nur 65535 gleichzeitige Verbindungen akzeptieren kann.

Zum Beispiel:

Wir haben eine Website erstellt und sie an TCP-Port 80 gebunden. Das Ergebnis ist, dass alle Benutzer, die diese Website besuchen, auf Port 80 des Servers zugreifen, nicht auf andere Ports. Sichtbare Ports können wiederverwendet werden. Selbst wenn der Linux-Server nur auf Port 80 auf Dienste wartet, können 100.000 oder 1 Million Benutzer eine Verbindung zum Server herstellen. Das Linux-System begrenzt die Anzahl der Verbindungen nicht. Ob der Server so viele Verbindungen aushält, hängt von der Hardwarekonfiguration, der Softwarearchitektur und der Optimierung des Servers ab.

01

Wir wissen, dass die grundlegendste Voraussetzung für die Kommunikation zweier Prozesse darin besteht, einen Prozess eindeutig identifizieren zu können. Bei der lokalen Prozesskommunikation können wir PID verwenden, um einen Prozess eindeutig zu identifizieren. PID ist jedoch nur lokal eindeutig und die Wahrscheinlichkeit eines PID-Konflikts zwischen zwei Prozessen im Netzwerk ist sehr hoch.

Zu diesem Zeitpunkt müssen Sie einen anderen Weg finden, um den Host eindeutig zu identifizieren, und das TCP-Layer-Protokoll und die Portnummer können einen Prozess des Hosts eindeutig identifizieren Mit dieser Nummer kann ein Prozess im Netzwerk eindeutig identifiziert werden.

Nachdem Prozesse im Netzwerk eindeutig identifiziert werden konnten, können sie über Sockets kommunizieren. Socket ist eine Abstraktionsschicht zwischen der Anwendungsschicht und der Transportschicht. Sie abstrahiert die komplexen Vorgänge der TCP/IP-Schicht in mehrere einfache Schnittstellen, die die Anwendungsschicht aufrufen und den Prozess zur Kommunikation im Netzwerk realisieren kann.

Socket stammt von Unix und ist eine Implementierung des „Open-Read/Write-Close“-Modus. Nachdem die Verbindung hergestellt und geöffnet wurde, können Server und Client schreiben Geben Sie den Inhalt ein, damit die andere Partei den Inhalt der anderen Partei lesen kann, und schließen Sie die Datei, wenn die Kommunikation endet.

02

Das Einzige, was eine Verbindung bestimmen kann, sind 4 Dinge:

1 Die IP des Servers

2. Port des Servers

3. IP des Clients

Die IP und der Port des Servers können gleich bleiben, solange sich die IP und der Port des Clients unterscheiden, kann eine Anzahl von Verbindungen bestimmt werden .

Ein Socket kann mehrere Verbindungen herstellen. Eine TCP-Verbindung wird als Vier-Tupel (Quell-IP, Quell-Port, Ziel-IP, Ziel-Port) markiert, d. h. (Quell-IP, Quell-Port, Ziel-IP, Ziel-Port). von Elementen. Solange ein Element in der Kombination von vier Elementen unterschiedlich ist, können verschiedene Verbindungen unterschieden werden.

Zum Beispiel:

->Ihre Host-IP-Adresse ist 1.1.1.1 und überwacht Port 8080

->Wenn eine Verbindungsanfrage von 2.2.2.2 kommt, ist der Port 5555. Das Vier-Tupel dieser Verbindung ist (1.1.1.1, 8080, 2.2.2.2, 5555)

->Zu diesem Zeitpunkt sendete 2.2.2.2 eine zweite Verbindungsanfrage mit dem Port 6666. Das Vier-Tupel der neuen Verbindung ist (1.1.1.1, 8080, 2.2.2.2, 6666)

Dann wurden

zwei Verbindungen auf Port 8080 Ihres Hosts hergestellt

;-> Gesendet von (2.2.2.2 ) Bei der dritten Verbindungsanforderung ist der Port 5555 (oder 6666). Die Anfrage für die dritte Verbindung kann nicht hergestellt werden, da es keine Möglichkeit gibt, sie von den beiden oben genannten Verbindungen zu unterscheiden.

In ähnlicher Weise

Sie können einen TCP-Socket und einen UDP-Socket an dieselbe Portnummer und IP-Adresse binden

Da die Portnummern gleich sind, aber die Protokolle unterschiedlich sind, sind die Ports völlig unabhängig.

TCP/UDP verwendet im Allgemeinen fünf Tupel, um eine Verbindung zu lokalisieren:

Quell-IP, Quell-Port, Ziel-IP, Ziel-Port, Protokolltyp

Das heißt (Quell-IP, Quell-Port, Ziel-IP, Ziel-Port, Protokollnummer)

Zusammenfassend lässt sich sagen, dass die Anzahl der gleichzeitigen Server nicht durch die 65535 Ports von TCP bestimmt wird. Die Anzahl der Parallelitäten, die ein Server gleichzeitig aushalten kann, wird von vielen Faktoren wie Bandbreite, Hardware und Programmdesign bestimmt.

Wir können also verstehen, warum Taobao, Tencent, Toutiao, Baidu, Sina, BeepBeep usw. Hunderte Millionen gleichzeitiger Zugriffe pro Sekunde aushalten können, weil sie Servercluster verwenden. Servercluster sind in großen Computerräumen über das ganze Land verteilt. Wenn die Anzahl der Besuche gering ist, werden einige Server heruntergefahren, und wenn die Anzahl der Besuche hoch ist, werden kontinuierlich neue Server eröffnet.

Gesunder Menschenverstand 1: Dateihandle-Einschränkungen

Freunde, die Netzwerkserverprogramme unter Linux schreiben, müssen wissen, dass jede TCP-Verbindung einen Dateideskriptor belegt. Sobald dieser Dateideskriptor aufgebraucht ist, wird eine neue Verbindung an unseren Fehler zurückgegeben

"Socket/Datei:Es können nicht so viele Dateien geöffnet werden"

. Zu diesem Zeitpunkt müssen Sie die Beschränkung des Betriebssystems hinsichtlich der maximalen Anzahl von Dateien verstehen, die geöffnet werden können.

    Prozessbeschränkungen
    • Die Ausführung von ulimit -n gibt 1024 aus, was bedeutet, dass ein Prozess nur bis zu 1024 Dateien öffnen kann. Wenn Sie also diese Standardkonfiguration verwenden, können Sie höchstens Tausende von TCP-Verbindungen gleichzeitig ausführen.
    • Vorübergehende Änderung: ulimit -n 1000000, diese vorübergehende Änderung gilt jedoch nur für die aktuelle Nutzungsumgebung des aktuell angemeldeten Benutzers und wird ungültig, nachdem das System neu gestartet oder der Benutzer abgemeldet wurde.
    • Änderungen, die nach dem Neustart ungültig werden (aber ich habe unter CentOS 6.5 getestet und nach dem Neustart keine Ungültigkeit festgestellt): Bearbeiten Sie die Datei /etc/security/limits.conf, und der geänderte Inhalt ist
    • * soft nofile 1000000

      * hard nofile 1000000* soft nofile 1000000

      * hard nofile 1000000

    • 永久修改:编辑/etc/rc.local,在其后添加如下内容

      ulimit -SHn 1000000

  • 全局限制

    • 执行 cat /proc/sys/fs/file-nr 输出 9344 0 592026,分别为:1.已经分配的文件句柄数,2.已经分配但没有使用的文件句柄数,3.最大文件句柄数。但在kernel 2.6版本中第二项的值总为0,这并不是一个错误,它实际上意味着已经分配的文件描述符无一浪费的都已经被使用了 。

    • 我们可以把这个数值改大些,用 root 权限修改 /etc/sysctl.conf 文件:

      fs.file-max = 1000000

      net.ipv4.ip_conntrack_max = 1000000

      net.ipv4.netfilter.ip_conntrack_max = 1000000

    Permanente Änderung: Bearbeiten Sie /etc/rc.local und fügen Sie den folgenden Inhalt danach hinzu
ulimit -SHn 1000000

Globale Einschränkungen

🎜🎜 Die Ausführung von cat /proc/sys/fs/file-nr gibt 9344 0 592026 aus, nämlich: 1. Die Anzahl der zugewiesenen Dateihandles, 2. Die Dateien die zugewiesen, aber nicht verwendet wurden. Anzahl der Handles, 3. Maximale Anzahl der Dateihandles. In der Kernel-Version 2.6 ist der Wert des zweiten Elements jedoch immer 0. Dies ist kein Fehler, sondern bedeutet tatsächlich, dass alle zugewiesenen Dateideskriptoren verwendet wurden. 🎜🎜🎜🎜Wir können diesen Wert in einen größeren Wert ändern und die Datei /etc/sysctl.conf mit Root-Berechtigungen ändern: 🎜🎜fs.file-max = 1000000🎜🎜net. ipv4. ip_conntrack_max = 1000000🎜🎜net.ipv4.netfilter.ip_conntrack_max = 1000000🎜🎜🎜🎜🎜🎜🎜Gesunder Menschenverstand 2: Portnummernbereichsbegrenzung? 🎜🎜🎜Portnummern unter 1024 auf dem Betriebssystem werden vom System reserviert und 1024-65535 werden von Benutzern verwendet. Da jede TCP-Verbindung eine Portnummer belegt, können wir bis zu mehr als 60.000 gleichzeitige Verbindungen haben. Ich glaube, es gibt viele Freunde, die diese falsche Vorstellung haben, oder? (Das habe ich in der Vergangenheit immer gedacht)🎜🎜Lass es uns analysieren🎜
  • So identifizieren Sie eine TCP-Verbindung: Das System verwendet ein 4-Tupel, um eine TCP-Verbindung eindeutig zu identifizieren: {lokale IP, lokaler Port, Remote-IP, Remote-Port}. Schauen wir uns nun die Erklärung von „accept“ in Kapitel 4 von „UNIX-Netzwerkprogrammierung: Band 1“ an und werfen einen Blick auf das Konzept. Der zweite Parameter cliaddr repräsentiert die IP-Adresse und die Portnummer des Clients. Als Server verwenden wir den Port tatsächlich nur während der Bindung, was zeigt, dass die Portnummer 65535 keine Grenze für den Umfang der Parallelität darstellt.

  • Maximale Anzahl von TCP-Verbindungen zum Server: Der Server ist normalerweise so festgelegt, dass er an einem lokalen Port lauscht und auf die Verbindungsanfrage des Clients wartet. Ohne Berücksichtigung der Wiederverwendung von Adressen (SO_REUSEADDR-Option von Unix) ist der lokale Überwachungsport exklusiv, selbst wenn auf der Serverseite mehrere IPs vorhanden sind, sodass die serverseitige TCP-Verbindung 4-Tupel nur Remote-IP (dh Client-IP) hat. und Remote-Port. (Client-Port) ist variabel, daher ist die maximale TCP-Verbindung die Anzahl der Client-IPs × die Anzahl der Client-Ports. Für IPV4 beträgt die maximale Anzahl von TCP-Verbindungen unabhängig von Faktoren wie der IP-Adressklassifizierung hoch 32 (Anzahl der IPs) × 2 hoch 16 (Anzahl der Ports), d. h. die maximale Anzahl von TCP-Verbindungen auf einer einzelnen Serverseite beträgt ungefähr 2 hoch 48.

Allgemeine Einstellungen

1. Ändern Sie die Begrenzung der Anzahl der Dateien, die von einem Benutzerprozess geöffnet werden können.

Auf der Linux-Plattform, unabhängig davon, ob Sie ein Client-Programm oder ein Serverprogramm schreiben, wenn die Verarbeitung hoch ist -Parallelität TCP-Verbindungen, die höchste Die Anzahl der Parallelitäten wird durch die Systembeschränkung für die Anzahl der Dateien begrenzt, die von einem einzelnen Benutzerprozess gleichzeitig geöffnet werden können (dies liegt daran, dass das System für jede TCP-Verbindung ein Socket-Handle erstellt). und jedes Socket-Handle ist auch ein Dateihandle). Sie können den Befehl ulimit verwenden, um die Grenze für die Anzahl der Dateien zu überprüfen, die das System dem aktuellen Benutzerprozess zum Öffnen erlaubt:

[speng@as4 ~]$ ulimit -n
1024

Das bedeutet, dass jeder Prozess des aktuellen Benutzers bis zu 1024 Dateien gleichzeitig öffnen darf Unter diesen 1024 Dateien müssen die Standarddateien, die jeder Prozess öffnen muss, entfernt werden Der für die Client-Socket-Verbindung verwendete Wert beträgt nur etwa 1024-10=1014. Das heißt, Linux-basierte Kommunikationsprogramme erlauben standardmäßig bis zu 1014 gleichzeitige TCP-Verbindungen.
Für Kommunikationshandler, die eine höhere Anzahl gleichzeitiger TCP-Verbindungen unterstützen möchten, müssen Sie das Soft-Limit (Soft Limit) und das Hard-Limit (Hardlimit) von Linux für die Anzahl der Dateien ändern, die gleichzeitig vom Prozess des aktuellen Benutzers geöffnet werden. Das weiche Limit bedeutet, dass Linux die Anzahl der Dateien, die der Benutzer gleichzeitig öffnen kann, innerhalb des Bereichs weiter begrenzt, den das aktuelle System ertragen kann. Das harte Limit ist die berechnete maximale Anzahl von Dateien, die das System gleichzeitig öffnen kann basierend auf den Hardwareressourcen des Systems (hauptsächlich Systemspeicher). Normalerweise ist das Soft-Limit kleiner oder gleich dem Hard-Limit.
Der einfachste Weg, die oben genannten Einschränkungen zu ändern, ist die Verwendung des Befehls ulimit:

[speng@as4 ~]$ ulimit -n

Geben Sie im obigen Befehl die maximale Anzahl von Dateien an, die von einem einzelnen Prozess geöffnet werden dürfen. Wenn das System etwas wie „Vorgang nicht zulässig“ ausgibt, bedeutet dies, dass die obige Grenzwertänderung fehlgeschlagen ist. Tatsächlich liegt dies daran, dass der in angegebene Wert das weiche oder harte Limit des Linux-Systems für die Anzahl der vom Benutzer geöffneten Dateien überschreitet. Daher ist es notwendig, die Soft- und Hard-Limits des Linux-Systems für die Anzahl geöffneter Dateien für Benutzer zu ändern.

Schritt 1: Ändern Sie die Datei /etc/security/limits.conf, fügen Sie die folgende Zeile in die Datei ein:

...
# End of file
speng soft nofile 10240
speng hard nofile 10240
root soft nofile 65535
root hard nofile 65535
* soft nofile 65535
* hard nofile 65535
[test@iZwz9e1dh1nweaex8ob5b7Z config]$

speng gibt an, welches Benutzerlimit für geöffnete Dateien geändert werden soll, und das Zeichen „*“ kann verwendet werden Wird verwendet, um die Änderungsgrenzen für alle Benutzer anzugeben; weich oder hart gibt an, ob die weiche Grenze oder die harte Grenze geändert werden soll. 10240 gibt den neuen Grenzwert an, den Sie ändern möchten, d. h. die maximale Anzahl geöffneter Dateien (bitte beachten Sie, dass die weiche Grenze geändert werden soll). Der Grenzwert muss kleiner oder gleich dem harten Grenzwert sein. Speichern Sie die Datei, nachdem Sie Änderungen vorgenommen haben.

Im zweiten Schritt ändern Sie die Datei /etc/pam.d/login und fügen Sie die folgende Zeile in die Datei ein:

session required /lib/security/pam_limits.so

Dadurch wird Linux mitgeteilt, dass es pam_limits.so aufrufen soll, nachdem der Benutzer die Systemanmeldung abgeschlossen hat Modul zum Festlegen des Systemlimits Das maximale Limit für die Anzahl verschiedener Ressourcen, die der Benutzer verwenden kann (einschließlich des Limits für die maximale Anzahl von Dateien, die der Benutzer öffnen kann), und das Modul pam_limits.so liest die Konfiguration aus dem / Öffnen Sie die Datei etc/security/limits.conf, um diese Grenzwerte festzulegen. Speichern Sie diese Datei nach der Änderung.

Der dritte Schritt: Überprüfen Sie die maximale Anzahl geöffneter Dateien auf Linux-Systemebene. Verwenden Sie den folgenden Befehl:

[speng@as4 ~]$ cat /proc/sys/fs/file-max
12158

Dies zeigt, dass dieses Linux-System das gleichzeitige Öffnen von maximal 12158 Dateien zulässt (das ist, einschließlich der Gesamtzahl der von allen Benutzern geöffneten Dateien. Es handelt sich um eine feste Grenze auf Linux-Systemebene. Alle Beschränkungen auf Benutzerebene für die Anzahl geöffneter Dateien sollten diesen Wert nicht überschreiten. Normalerweise ist dieses harte Limit auf Systemebene die optimale maximale Anzahl gleichzeitig geöffneter Dateien, die auf der Grundlage der Systemhardwareressourcen beim Start des Linux-Systems berechnet wird. Wenn kein besonderer Bedarf besteht, sollte dieses Limit nicht geändert werden, es sei denn, Sie möchten es begrenzen Die Anzahl der auf Benutzerebene geöffneten Dateien. Legen Sie einen Wert fest, der diesen Grenzwert überschreitet. Die Möglichkeit, dieses harte Limit zu ändern, besteht darin, das Skript /etc/rc.local zu ändern und die folgende Zeile zum Skript hinzuzufügen:

echo 22158 > /proc/sys/fs/file-max

Dadurch wird Linux gezwungen, das harte Limit auf Systemebene für die Anzahl geöffneter Dateien festzulegen 22158 nach Abschluss des Startvorgangs. Speichern Sie diese Datei nach der Änderung.

完成上述步骤后重启系统,一般情况下就可以将Linux系统对指定用户的单一进程允许同时打开的最大文件数限制设为指定的数值。如果重启后用 ulimit-n命令查看用户可打开文件数限制仍然低于上述步骤中设置的最大值,这可能是因为在用户登录脚本/etc/profile中使用ulimit -n命令已经将用户可同时打开的文件数做了限制。由于通过ulimit-n修改系统对用户可同时打开文件的最大数限制时,新修改的值只能小于或等于上次 ulimit-n设置的值,因此想用此命令增大这个限制值是不可能的。所以,如果有上述问题存在,就只能去打开/etc/profile脚本文件,在文件中查找是否使用了ulimit-n限制了用户可同时打开的最大文件数量,如果找到,则删除这行命令,或者将其设置的值改为合适的值,然后保存文件,用户退出并重新登录系统即可。

通过上述步骤,就为支持高并发TCP连接处理的通讯处理程序解除关于打开文件数量方面的系统限制。

2、修改网络内核对TCP连接的有关限制(参考对比下篇文章“优化内核参数”)

在Linux上编写支持高并发TCP连接的客户端通讯处理程序时,有时会发现尽管已经解除了系统对用户同时打开文件数的限制,但仍会出现并发TCP连接数增加到一定数量时,再也无法成功建立新的TCP连接的现象。出现这种现在的原因有多种。

第一种原因可能是因为Linux网络内核对本地端口号范围有限制。此时,进一步分析为什么无法建立TCP连接,会发现问题出在connect()调用返回失败,查看系统错误提示消息是“Can’t assign requestedaddress”。同时,如果在此时用tcpdump工具监视网络,会发现根本没有TCP连接时客户端发SYN包的网络流量。这些情况说明问题在于本地Linux系统内核中有限制。其实,问题的根本原因在于Linux内核的TCP/IP协议实现模块对系统中所有的客户端TCP连接对应的本地端口号的范围进行了限制(例如,内核限制本地端口号的范围为1024~32768之间)。当系统中某一时刻同时存在太多的TCP客户端连接时,由于每个TCP客户端连接都要占用一个唯一的本地端口号(此端口号在系统的本地端口号范围限制中),如果现有的TCP客户端连接已将所有的本地端口号占满,则此时就无法为新的TCP客户端连接分配一个本地端口号了,因此系统会在这种情况下在connect()调用中返回失败,并将错误提示消息设为“Can’t assignrequested address”。有关这些控制逻辑可以查看Linux内核源代码,以linux2.6内核为例,可以查看tcp_ipv4.c文件中如下函数:

static int tcp_v4_hash_connect(struct sock *sk)

请注意上述函数中对变量sysctl_local_port_range的访问控制。变量sysctl_local_port_range的初始化则是在tcp.c文件中的如下函数中设置:

void __init tcp_init(void)

内核编译时默认设置的本地端口号范围可能太小,因此需要修改此本地端口范围限制。

第一步,修改/etc/sysctl.conf文件,在文件中添加如下行:

net.ipv4.ip_local_port_range = 1024 65000

这表明将系统对本地端口范围限制设置为1024~65000之间。请注意,本地端口范围的最小值必须大于或等于1024;而端口范围的最大值则应小于或等于65535。修改完后保存此文件。

第二步,执行sysctl命令:

[speng@as4 ~]$ sysctl -p

如果系统没有错误提示,就表明新的本地端口范围设置成功。如果按上述端口范围进行设置,则理论上单独一个进程最多可以同时建立60000多个TCP客户端连接。

第二种无法建立TCP连接的原因可能是因为Linux网络内核的IP_TABLE防火墙对最大跟踪的TCP连接数有限制。此时程序会表现为在 connect()调用中阻塞,如同死机,如果用tcpdump工具监视网络,也会发现根本没有TCP连接时客户端发SYN包的网络流量。由于 IP_TABLE防火墙在内核中会对每个TCP连接的状态进行跟踪,跟踪信息将会放在位于内核内存中的conntrackdatabase中,这个数据库的大小有限,当系统中存在过多的TCP连接时,数据库容量不足,IP_TABLE无法为新的TCP连接建立跟踪信息,于是表现为在connect()调用中阻塞。此时就必须修改内核对最大跟踪的TCP连接数的限制,方法同修改内核对本地端口号范围的限制是类似的:
第一步,修改/etc/sysctl.conf文件,在文件中添加如下行:

net.ipv4.ip_conntrack_max = 10240

这表明将系统对最大跟踪的TCP连接数限制设置为10240。请注意,此限制值要尽量小,以节省对内核内存的占用。

第二步,执行sysctl命令:

[speng@as4 ~]$ sysctl -p

如果系统没有错误提示,就表明系统对新的最大跟踪的TCP连接数限制修改成功。如果按上述参数进行设置,则理论上单独一个进程最多可以同时建立10000多个TCP客户端连接。

3、使用支持高并发网络I/O的编程技术

在Linux上编写高并发TCP连接应用程序时,必须使用合适的网络I/O技术和I/O事件分派机制。
可用的I/O技术有同步I/O,非阻塞式同步I/O(也称反应式I/O),以及异步I/O。《BIO,NIO,AIO的理解》

在高TCP并发的情形下,如果使用同步I/O,这会严重阻塞程序的运转,除非为每个TCP连接的I/O创建一个线程。但是,过多的线程又会因系统对线程的调度造成巨大开销。因此,在高TCP并发的情形下使用同步 I/O是不可取的,这时可以考虑使用非阻塞式同步I/O或异步I/O。非阻塞式同步I/O的技术包括使用select(),poll(),epoll等机制。异步I/O的技术就是使用AIO。
从I/O事件分派机制来看,使用select()是不合适的,因为它所支持的并发连接数有限(通常在1024个以内)。如果考虑性能,poll()也是不合适的,尽管它可以支持的较高的TCP并发数,但是由于其采用“轮询”机制,当并发数较高时,其运行效率相当低,并可能存在I/O事件分派不均,导致部分TCP连接上的I/O出现“饥饿”现象。而如果使用epoll或AIO,则没有上述问题(早期Linux内核的AIO技术实现是通过在内核中为每个 I/O请求创建一个线程来实现的,这种实现机制在高并发TCP连接的情形下使用其实也有严重的性能问题。但在最新的Linux内核中,AIO的实现已经得到改进)。
综上所述,在开发支持高并发TCP连接的Linux应用程序时,应尽量使用epoll或AIO技术来实现并发的TCP连接上的I/O控制,这将为提升程序对高并发TCP连接的支持提供有效的I/O保证。

内核参数sysctl.conf的优化

/etc/sysctl.conf 是用来控制linux网络的配置文件,对于依赖网络的程序(如web服务器和cache服务器)非常重要,RHEL默认提供的最好调整。

推荐配置(把原/etc/sysctl.conf内容清掉,把下面内容复制进去):

net.ipv4.ip_local_port_range = 1024 65536
net.core.rmem_max=16777216
net.core.wmem_max=16777216
net.ipv4.tcp_rmem=4096 87380 16777216
net.ipv4.tcp_wmem=4096 65536 16777216
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_window_scaling = 0
net.ipv4.tcp_sack = 0
net.core.netdev_max_backlog = 30000
net.ipv4.tcp_no_metrics_save=1
net.core.somaxconn = 262144
net.ipv4.tcp_syncookies = 0
net.ipv4.tcp_max_orphans = 262144
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2

这个配置参考于cache服务器varnish的推荐配置和SunOne 服务器系统优化的推荐配置。

varnish调优推荐配置的地址为:http://varnish.projects.linpro.no/wiki/Performance

不过varnish推荐的配置是有问题的,实际运行表明“net.ipv4.tcp_fin_timeout = 3”的配置会导致页面经常打不开;并且当网友使用的是IE6浏览器时,访问网站一段时间后,所有网页都会打不开,重启浏览器后正常。可能是国外的网速快吧,我们国情决定需要调整“net.ipv4.tcp_fin_timeout = 10”,在10s的情况下,一切正常(实际运行结论)。

修改完毕后,执行:

/sbin/sysctl -p /etc/sysctl.conf
/sbin/sysctl -w net.ipv4.route.flush=1

命令生效。为了保险起见,也可以reboot系统。

调整文件数:

linux系统优化完网络必须调高系统允许打开的文件数才能支持大的并发,默认1024是远远不够的。

执行命令:

echo ulimit -HSn 65536 >> /etc/rc.local
echo ulimit -HSn 65536 >>/root/.bash_profile
ulimit -HSn 65536

备注:

对mysql用户可同时打开文件数设置为10240个;
将Linux系统可同时打开文件数设置为1000000个(一定要大于对用户的同时打开文件数限制);
将Linux系统对最大追踪的TCP连接数限制为20000个(但是,建议设置为10240;因为对mysql用户的同时打开文件数已经限制在10240个;且较小的值可以节省内存);
将linux系统端口范围配置为1024~30000(可以支持60000个以上连接,不建议修改;默认已经支持20000个以上连接);

综合上述四点,TCP连接数限制在10140个。
这10240个文件中还得除去每个进程必然打开的标准输入,标准输出,标准错误,服务器监听 socket,进程间通讯的unix域socket等文件。

因此,当需要对TCP连接数进行调整时只需要调整ulimit参数。

Linux下查看tcp连接数及状态命令:

netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

相关推荐:《Linux视频教程

Das obige ist der detaillierte Inhalt vonWelche Faktoren beeinflussen die Anzahl der TCP-Verbindungen im Linux-System?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn