Maison  >  Article  >  Opération et maintenance  >  Quels facteurs affectent le nombre de connexions TCP dans le système Linux

Quels facteurs affectent le nombre de connexions TCP dans le système Linux

青灯夜游
青灯夜游original
2022-11-07 18:47:382163parcourir

Les principaux facteurs qui affectent le nombre de connexions TCP dans le système Linux sont la mémoire et le nombre de descripteurs de fichiers autorisés, car chaque connexion TCP occupe une certaine quantité de mémoire et chaque socket est un descripteur de fichier. De plus, les ports ci-dessous. 1024 généralement Un port réservé.

Quels facteurs affectent le nombre de connexions TCP dans le système Linux

L'environnement d'exploitation de ce tutoriel : système linux7.3, ordinateur Dell G3.

Dans les applications TCP, le serveur écoute à l'avance sur un port fixe, le client initie activement une connexion et la connexion TCP est établie après une poignée de main à trois. Alors pour une seule machine, quel est le nombre maximum de connexions TCP simultanées ?

Comment identifier une connexion TCP

Avant de déterminer le nombre maximum de connexions, examinons d'abord comment le système identifie une connexion TCP. Le système utilise un 4-tuple pour identifier de manière unique une connexion TCP : {localip, localport,remoteip,remoteport}.

Nombre maximum de connexions TCP pour le client

Chaque fois qu'un client lance une demande de connexion TCP, à moins que le port ne soit lié, le système sélectionnera généralement un port local inactif (port local). ne peut pas être utilisé avec D'autres connexions TCP sont partagées. Le type de données du port TCP est non signé, donc le nombre maximum de ports locaux n'est que de 65 536. Le port 0 a une signification particulière et ne peut pas être utilisé de cette manière, les ports disponibles ne sont donc que de 65 535 au maximum. sont utilisés comme clients, le nombre maximum de connexions TCP pour un client est de 65535, ces connexions peuvent être connectées à différents serveurs.

Le nombre maximum de connexions TCP pour le serveur

le serveur est généralement fixé pour écouter sur un port local, en attendant la demande de connexion du client. Sans considérer la réutilisation des adresses (l'option SO_REUSEADDR d'Unix), même s'il y a plusieurs adresses IP côté serveur, le port d'écoute local est exclusif. Par conséquent, il n'y a que l'adresse IP distante (c'est-à-dire l'adresse IP client) et le port distant (client). 4-tuple de la connexion TCP côté serveur) est variable, donc la connexion TCP maximale est le nombre d'IP client × le nombre de ports client pour IPV4, quels que soient des facteurs tels que la classification des adresses IP, le nombre maximum de. Les connexions TCP sont d'environ 2 puissance 32 (nombre d'adresses IP) × 2 puissance 16 (nombre de ports), c'est-à-dire que le nombre maximum de connexions TCP sur une seule machine côté serveur est d'environ 2 puissance 48. .

Le nombre réel de connexions TCP

Ce qui précède est le nombre maximum théorique de connexions pour une seule machine. Dans l'environnement réel, il est limité par les ressources de la machine, les systèmes d'exploitation, etc., notamment côté serveur. , dont le nombre maximal de connexions TCP simultanées est loin d'atteindre la limite supérieure théorique. Les principaux facteurs qui limitent le nombre de connexions sous Unix/Linux sont la mémoire et le nombre de descripteurs de fichiers autorisés (chaque connexion TCP occupe une certaine quantité de mémoire, et chaque socket est un descripteur de fichier. De plus, les ports inférieurs à 1024 sont généralement). port réservé. Sous la configuration par défaut du noyau 2.6, après tests, chaque socket occupe entre 15 et 20 Ko de mémoire.

Ainsi, côté serveur, en augmentant la mémoire et en modifiant des paramètres tels que le nombre maximum de descripteurs de fichiers, il n'y a aucun problème à augmenter le nombre maximum de connexions TCP simultanées sur une seule machine à plus de 100 000, voire des millions.

Il s'agit évidemment d'un malentendu. 65535 fait référence au nombre total de ports disponibles. Cela ne signifie pas que le serveur ne peut accepter que 65535 connexions simultanées.

Par exemple :

Nous avons créé un site Web et l'avons lié au port TCP 80. Le résultat est que tous les utilisateurs qui visitent ce site Web accèdent au port 80 du serveur, pas aux autres ports. Les ports visibles peuvent être réutilisés. Même si le serveur Linux n'écoute que les services sur le port 80, il permet à 100 000 ou 1 million d'utilisateurs de se connecter au serveur. Le système Linux ne limite pas le nombre de connexions. La capacité du serveur à supporter autant de connexions dépend de la configuration matérielle, de l'architecture logicielle et de l'optimisation du serveur.

01

Nous savons que la condition préalable la plus fondamentale pour que deux processus communiquent est de pouvoir identifier de manière unique un processus. Dans la communication de processus locaux, nous pouvons utiliser le PID pour identifier un processus de manière unique, mais le PID n'est unique que localement et la probabilité d'un conflit PID entre deux processus du réseau est très élevée.

À ce stade, vous devez trouver un autre moyen. L'adresse IP peut identifier de manière unique l'hôte, et le protocole de couche TCP et le numéro de port peuvent identifier de manière unique un processus de l'hôte. De cette manière, l'adresse IP + le protocole + le port. Le numéro peut être utilisé pour identifier de manière unique un processus dans le processus réseau.

Après avoir pu identifier de manière unique les processus sur le réseau, ils peuvent communiquer à l'aide de sockets. Socket est une couche d'abstraction entre la couche application et la couche transport. Il résume les opérations complexes de la couche TCP/IP en quelques interfaces simples permettant à la couche application d'appeler et de mettre en œuvre des processus pour communiquer dans le réseau.

Socket est originaire d'Unix et est une implémentation du mode "ouvrir-lecture/écriture-fermeture". Le serveur et le client conservent chacun un "fichier". Une fois la connexion établie et ouverte, ils peuvent. écrire dans leurs propres fichiers. Saisissez le contenu pour que l'autre partie lise ou lise le contenu de l'autre partie, et fermez le fichier à la fin de la communication.

02

La seule chose qui peut déterminer une connexion est 4 choses :

1. IP du serveur

.

2. Port du serveur

3. IP du client

4. Port du client

L'IP et le port du serveur peuvent rester les mêmes, tant que l'IP et le port du client sont différents l'un de l'autre, un certain nombre de connexions peuvent être déterminées. .

Une socket peut établir plusieurs connexions. Une connexion TCP est marquée comme un quadruple (source_ip, source_port, destination_ip, destination_port), c'est-à-dire (source IP, source port, destination IP, destination port) quatre combinaisons. d'éléments. Tant qu’un élément de la combinaison de quatre éléments est différent, différentes connexions peuvent être distinguées.

Par exemple :

->Votre adresse IP hôte est 1.1.1.1, en écoute sur le port 8080

->Lorsqu'une demande de connexion provient du 2.2.2.2, le port est 5555. Le quadruple de cette connexion est (1.1.1.1, 8080, 2.2.2.2, 5555)

->A ce moment, 2.2.2.2 a envoyé une deuxième demande de connexion avec le port 6666. Le quadruple de la nouvelle connexion est (1.1.1.1, 8080, 2.2.2.2, 6666)

Ensuite, deux connexions ont été établies sur le port 8080 de votre hôte;

-> ) La troisième demande de connexion, le port est 5555 (ou 6666). La demande de troisième connexion ne peut pas être établie car il n'existe aucun moyen de la distinguer des deux connexions ci-dessus.

De même, Vous pouvez lier un socket TCP et un socket UDP sur le même numéro de port et la même adresse IP

Parce que les numéros de port sont les mêmes, mais les protocoles sont différents, donc les ports sont complètement indépendants.

TCP/UDP utilise généralement cinq tuples pour localiser une connexion :

source_ip, source_port, destination_ip, destination_port, protocol_type

C'est-à-dire (IP source, port source, IP de destination, port de destination, numéro de protocole)

Pour résumer, le nombre de serveurs simultanés n'est pas déterminé par les 65535 ports TCP. Le nombre de simultanéités qu'un serveur peut supporter en même temps est déterminé par de nombreux facteurs tels que la bande passante, le matériel et la conception du programme.

On comprend donc pourquoi Taobao, Tencent, Toutiao, Baidu, Sina, BeepBeep, etc. peuvent supporter des centaines de millions d'accès simultanés par seconde, car ils utilisent des clusters de serveurs. Les clusters de serveurs sont répartis dans de grandes salles informatiques à travers le pays. Lorsque le nombre de visites est faible, certains serveurs seront arrêtés, et lorsque le nombre de visites est élevé, de nouveaux serveurs seront ouverts en permanence.

Bon sens 1 : Restrictions de gestion de fichiers

Les amis qui écrivent des programmes de serveur réseau sous Linux doivent savoir que chaque connexion TCP occupe un descripteur de fichier. Une fois ce descripteur de fichier épuisé, une nouvelle connexion sera renvoyée à Notre erreur était. "Socket/Fichier : impossible d'ouvrir autant de fichiers".

À ce stade, vous devez comprendre la limite du système d'exploitation concernant le nombre maximum de fichiers pouvant être ouverts.

  • Limites du processus

    • L'exécution de ulimit -n génère 1024, indiquant qu'un processus ne peut ouvrir que jusqu'à 1024 fichiers, donc si vous utilisez cette configuration par défaut, vous pouvez exécuter simultanément des milliers de connexions TCP au maximum.

    • Modification temporaire : ulimit -n 1000000, mais cette modification temporaire n'est efficace que pour l'environnement d'utilisation actuel de l'utilisateur actuellement connecté et deviendra invalide après le redémarrage du système ou la déconnexion de l'utilisateur.

    • Modifications qui deviennent invalides après redémarrage (mais j'ai testé sous CentOS 6.5 et n'ai trouvé aucune invalidité après redémarrage) : Editez le fichier /etc/security/limits.conf, et le contenu modifié est

      * soft nofile 1000000<code>* 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

      * hard nofile 1000000
Modification permanente : éditez /etc/rc.local et ajoutez le contenu suivant après

ulimit -SHn 1000000

Limites globales 🎜🎜🎜🎜 L'exécution de cat /proc/sys/fs/file-nr génère 9344 0 592026, qui sont : 1. Le nombre de descripteurs de fichiers qui ont été alloués, 2. Les fichiers qui ont été alloués mais non utilisés Nombre de descripteurs, 3. Nombre maximum de descripteurs de fichiers. Mais dans la version 2.6 du noyau, la valeur du deuxième élément est toujours 0. Ce n'est pas une erreur, cela signifie en fait que tous les descripteurs de fichiers alloués ont été utilisés. 🎜🎜🎜🎜Nous pouvons changer cette valeur en une valeur plus grande et modifier le fichier /etc/sysctl.conf avec les autorisations root : 🎜🎜fs.file-max = 1000000🎜🎜net. ipv4.ip_conntrack_max = 1000000🎜🎜net.ipv4.netfilter.ip_conntrack_max = 1000000🎜🎜🎜🎜🎜🎜🎜Bon sens 2 : Limite de plage de numéros de port ? 🎜🎜🎜Les numéros de port inférieurs à 1024 sur le système d'exploitation sont réservés par le système et 1024-65535 sont utilisés par les utilisateurs. Puisque chaque connexion TCP occupe un numéro de port, nous pouvons avoir jusqu'à plus de 60 000 connexions simultanées. Je pense qu'il n'y a pas beaucoup d'amis qui ont cette fausse idée, n'est-ce pas ? (Je l’ai toujours pensé dans le passé)🎜🎜Analysons-le🎜
  • Comment identifier une connexion TCP : Le système utilise un 4-tuple pour identifier de manière unique une connexion TCP : {adresse IP locale, port local, adresse IP distante, port distant}. Eh bien, reprenons l'explication de accept dans le chapitre 4 de « Programmation réseau UNIX : Volume 1 » et jetons un coup d'œil aux éléments conceptuels. Le deuxième paramètre cliaddr représente l'adresse IP et le numéro de port du client. En tant que serveur, nous n'utilisons le port que pendant la liaison, ce qui montre que le numéro de port 65535 ne constitue pas une limite sur le degré de concurrence.

  • Nombre maximum de connexions TCP au serveur : Le serveur est généralement fixé pour écouter sur un port local, en attente de la demande de connexion du client. Sans considérer la réutilisation des adresses (option SO_REUSEADDR d'Unix), même s'il y a plusieurs adresses IP côté serveur, le port d'écoute local est exclusif, donc la connexion TCP côté serveur 4-tuple n'a qu'une adresse IP distante (c'est-à-dire une adresse IP client) et le port distant (port client) est variable, donc la connexion TCP maximale est le nombre d'IP client × le nombre de ports client. Pour IPV4, quels que soient les facteurs tels que la classification des adresses IP, le nombre maximum de connexions TCP est d'environ 2. à la 32ème puissance (nombre d'IP) )×2 à la 16ème puissance (nombre de ports), c'est-à-dire que le nombre maximum de connexions TCP sur une seule machine côté serveur est d'environ 2 à la 48ème puissance.

Paramètres communs

1. Modifier la limite du nombre de fichiers pouvant être ouverts par un processus utilisateur

Sur la plateforme Linux, qu'il s'agisse d'écrire un programme client ou un programme serveur, lors d'un traitement élevé -Connexions TCP concurrentes, le plus élevé. Le nombre de concurrences est soumis à la limite du système sur le nombre de fichiers pouvant être ouverts par un seul processus utilisateur en même temps (en effet, le système crée un handle de socket pour chaque connexion TCP, et chaque handle de socket est également un handle de fichier). Vous pouvez utiliser la commande ulimit pour afficher la limite du nombre de fichiers que le système autorise le processus utilisateur actuel à ouvrir :

[speng@as4 ~]$ ulimit -n
1024

Cela signifie que chaque processus de l'utilisateur actuel est autorisé à ouvrir jusqu'à 1024 fichiers en même temps. . Parmi ces 1024 fichiers, il faut supprimer le standard que chaque processus doit ouvrir. Entrée, sortie standard, erreur standard, socket d'écoute du serveur, socket de domaine unix pour la communication inter-processus et autres fichiers, puis le nombre de fichiers restants pouvant être ouverts. utilisé pour la connexion par socket client n'est que d'environ 1024-10=1014. Autrement dit, par défaut, les programmes de communication basés sur Linux autorisent jusqu'à 1 014 connexions TCP simultanées en même temps.
Pour les gestionnaires de communication qui souhaitent prendre en charge un nombre plus élevé de connexions TCP simultanées, vous devez modifier la limite logicielle (soft limit) et la limite matérielle (hardlimit) de Linux sur le nombre de fichiers ouverts simultanément par le processus de l'utilisateur actuel. La limite souple signifie que Linux limite davantage le nombre de fichiers que l'utilisateur peut ouvrir en même temps dans la plage que le système actuel peut supporter ; la limite stricte est le nombre maximum de fichiers que le système peut ouvrir en même temps calculé ; en fonction des ressources matérielles du système (principalement la mémoire système). Habituellement, la limite souple est inférieure ou égale à la limite stricte.
Le moyen le plus simple de modifier les restrictions ci-dessus est d'utiliser la commande ulimit :

[speng@as4 ~]$ ulimit -n

Dans la commande ci-dessus, spécifiez le nombre maximum de fichiers autorisés à être ouverts par un seul processus à définir. Si le système renvoie quelque chose comme "Opération non autorisée", cela signifie que la modification de la limite ci-dessus a échoué. En fait, c'est parce que la valeur spécifiée dans dépasse la limite logicielle ou la limite stricte du système Linux sur le nombre de fichiers ouverts par l'utilisateur. Par conséquent, il est nécessaire de modifier les limites souples et strictes du système Linux concernant le nombre de fichiers ouverts pour les utilisateurs.

Étape 1, modifiez le fichier /etc/security/limits.conf, ajoutez la ligne suivante dans le fichier :

...
# 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 spécifie quelle limite de fichiers ouverts de l'utilisateur doit être modifiée, et le signe '*' peut être utilisé pour indiquer les limites de modification pour tous les utilisateurs ; soft ou hard spécifie s'il faut modifier la limite soft ou la limite hard ; 10240 spécifie la nouvelle valeur limite que vous souhaitez modifier, c'est-à-dire le nombre maximum de fichiers ouverts (veuillez noter que le soft la valeur limite doit être inférieure ou égale à la limite stricte). Enregistrez le fichier après avoir apporté des modifications.

La deuxième étape, modifiez le fichier /etc/pam.d/login et ajoutez la ligne suivante dans le fichier :

session required /lib/security/pam_limits.so

Cela indique à Linux qu'une fois que l'utilisateur a terminé la connexion au système, il doit appeler pam_limits.so module pour définir la limite du système La limite maximale du nombre de ressources diverses que l'utilisateur peut utiliser (y compris la limite du nombre maximum de fichiers que l'utilisateur peut ouvrir), et le module pam_limits.so lira la configuration à partir du / Fichier etc/security/limits.conf pour définir ces valeurs limites. Enregistrez ce fichier après modification.

La troisième étape, vérifiez le nombre maximum de fichiers ouverts au niveau du système Linux, utilisez la commande suivante :

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

Cela montre que ce système Linux permet d'ouvrir un maximum de 12158 fichiers en même temps (cela (y compris le nombre total de fichiers ouverts par tous les utilisateurs), il s'agit d'une limite stricte au niveau du système Linux. Toutes les limites au niveau de l'utilisateur sur le nombre de fichiers ouverts ne doivent pas dépasser cette valeur. Habituellement, cette limite stricte au niveau du système est le nombre maximum optimal de fichiers ouverts en même temps, calculé en fonction des ressources matérielles du système au démarrage du système Linux. S'il n'y a pas de besoin particulier, cette limite ne doit pas être modifiée, sauf si vous souhaitez la limiter. le nombre de fichiers ouverts au niveau de l'utilisateur. Définissez une valeur qui dépasse cette limite. La façon de modifier cette limite stricte est de modifier le script /etc/rc.local et d'ajouter la ligne suivante au script :

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

Ceci vise à forcer Linux à définir la limite stricte au niveau du système sur le nombre de fichiers ouverts à 22158 une fois le démarrage terminé. Enregistrez ce fichier après modification.

完成上述步骤后重启系统,一般情况下就可以将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 &#39;/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}&#39;

相关推荐:《Linux视频教程

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn