Maison  >  Article  >  Opération et maintenance  >  Optimisation des paramètres du système Linux et du noyau dans des conditions de concurrence élevée

Optimisation des paramètres du système Linux et du noyau dans des conditions de concurrence élevée

Linux中文社区
Linux中文社区avant
2023-08-04 16:41:19911parcourir

Il est bien connu que Linux ne prend pas bien en charge la concurrence élevée avec les paramètres par défaut, qui sont principalement limités par le nombre maximum de fichiers ouverts dans un seul processus, les paramètres TCP du noyau et le mécanisme de distribution des événements IO. Ce qui suit apportera des ajustements sous plusieurs aspects pour permettre au système Linux de prendre en charge les environnements à haute concurrence.

Iptables liés

Si cela n'est pas nécessaire, désactivez ou désinstallez le pare-feu iptables et empêchez le noyau de charger le module iptables. Ces modules peuvent affecter les performances de concurrence.

Limitation du nombre maximum de fichiers ouverts par un seul processus

Les distributions générales limitent un seul processus à un maximum de 1024 fichiers, ce qui est loin de répondre aux exigences élevées de concurrence. Le processus d'ajustement est le suivant : tapez au niveau du bouton. # invite Entrez :

# ulimit–n 65535

Définissez le nombre maximum de fichiers pouvant être ouverts par un seul processus démarré par root sur 65535. 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, la valeur spécifiée dépasse la limite logicielle ou la limite stricte du système Linux concernant le nombre de fichiers que l'utilisateur peut ouvrir. 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.

La première étape consiste à modifier le fichier limites.conf et à ajouter :

# vim /etc/security/limits.conf
* softnofile 65536
* hard nofile65536

Le signe '*' indique la modification des limites de tous les utilisateurs ; soft ou hard précise s'il faut modifier la limite soft ou la limite hard ; ceux que vous souhaitez modifier La nouvelle valeur limite est le nombre maximum de fichiers ouverts (veuillez noter que la valeur limite souple doit être inférieure ou égale à la limite stricte). Enregistrez le fichier après avoir apporté des modifications. La deuxième étape consiste à modifier le fichier /etc/pam.d/login et à ajouter la ligne suivante au fichier :

# vim /etc/pam.d/login
sessionrequired /lib/security/pam_limits.so

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

第三步,查看Linux系统级的最大打开文件数限制,使用如下命令:

# cat/proc/sys/fs/file-max
32568

这表明这台Linux系统最多允许同时打开(即包含所有用户打开文件数总和)32568个文件,是Linux系统级硬限制,所有用户级的打开文件数限制都不应超过这个数值。通常这个系统级硬限制是Linux系统在启动时根据系统硬件资源状况计算出来的最佳的最大同时打开文件数限制,如果没有特殊需要,不应该修改此限制,除非想为用户级打开文件数限制设置超过此限制的值。修改此硬限制的方法是修改/etc/sysctl.conf文件内fs.file-max= 131072

这是让Linux在启动完成后强行将系统级打开文件数硬限制设置为131072。修改完后保存此文件。

完成上述步骤后重启系统,一般情况下就可以将Linux系统对指定用户的单一进程允许同时打开的最大文件数限制设为指定的数值。如果重启后用ulimit-n命令查看用户可打开文件数限制仍然低于上述步骤中设置的最大值,这可能是因为在用户登录脚本/etc/profile中使用ulimit-n命令已经将用户可同时打开的文件数做了限制。

由于通过ulimit-n修改系统对用户可同时打开文件的最大数限制时,新修改的值只能小于或等于上次ulimit-n设置的值,因此想用此命令增大这个限制值是不可能的。所以,如果有上述问题存在,就只能去打开/etc/profile脚本文件,在文件中查找是否使用了ulimit-n限制了用户可同时打开的最大文件数量,如果找到,则删除这行命令,或者将其设置的值改为合适的值,然后保存文件,用户退出并重新登录系统即可。

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

内核TCP参数方面

Linux系统下,TCP连接断开后,会以TIME_WAIT状态保留一定的时间,然后才会释放端口。当并发请求过多的时候,就会产生大量的TIME_WAIT状态的连接,无法及时断开的话,会占用大量的端口资源和服务器资源。这个时候我们可以优化TCP的内核参数,来及时将TIME_WAIT状态的端口清理掉。

下面介绍的方法只对拥有大量TIME_WAIT状态的连接导致系统资源消耗有效,如果不是这种情况下,效果可能不明显。可以使用netstat命令去查TIME_WAIT状态的连接状态,输入下面的组合命令,查看当前TCP连接的状态和对应的连接数量:

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

这个命令会输出类似下面的结果:

LAST_ACK16
SYN_RECV348
ESTABLISHED70
FIN_WAIT1229
FIN_WAIT230
CLOSING33
TIME_WAIT18098

我们只用关心TIME_WAIT的个数,在这里可以看到,有18000多个TIME_WAIT,这样就占用了18000多个端口。要知道端口的数量只有65535个,占用一个少一个,会严重的影响到后继的新连接。这种情况下,我们就有必要调整下Linux的TCP内核参数,让系统更快的释放TIME_WAIT连接。

编辑配置文件:/etc/sysctl.conf,在这个文件中,加入下面的几行内容:

# vim /etc/sysctl.conf
net.ipv4.tcp_syncookies= 1
net.ipv4.tcp_tw_reuse= 1
net.ipv4.tcp_tw_recycle= 1
net.ipv4.tcp_fin_timeout= 30

输入下面的命令,让内核参数生效:

# sysctl-p

简单的说明上面的参数的含义:

  • net.ipv4.tcp_syncookies= 1 表示开启SYNCookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
  • net.ipv4.tcp_tw_reuse= 1 表示开启重用。允许将TIME-WAITsockets重新用于新的TCP连接,默认为0,表示关闭;
  • net.ipv4.tcp_tw_recycle= 1 表示开启TCP连接中TIME-WAITsockets的快速回收,默认为0,表示关闭;
  • net.ipv4.tcp_fin_timeout 修改系統默认的TIMEOUT 时间。

在经过这样的调整之后,除了会进一步提升服务器的负载能力之外,还能够防御小流量程度的DoS、CC和SYN攻击。

此外,如果你的连接数本身就很多,我们可以再优化一下TCP的可使用端口范围,进一步提升服务器的并发能力。依然是往上面的参数文件中,加入下面这些配置:

net.ipv4.tcp_keepalive_time= 1200
net.ipv4.ip_local_port_range= 1024 65535
net.ipv4.tcp_max_syn_backlog= 8192
net.ipv4.tcp_max_tw_buckets= 5000

这几个参数,建议只在流量非常大的服务器上开启,会有显著的效果。一般的流量小的服务器上,没有必要去设置这几个参数。

  • net.ipv4.tcp_keepalive_time= 1200 indique la fréquence à laquelle TCP envoie des messages keepalive lorsque keepalive est activé. La valeur par défaut est de 2 heures, remplacez-la par 20 minutes.
  • ip_local_port_range= 1024 65535 indique la plage de ports utilisée pour les connexions sortantes. La valeur par défaut est très petite, modifiée de 1024 à 65535.
  • net.ipv4.tcp_max_syn_backlog= 8192 indique la longueur de la file d'attente SYN, la valeur par défaut est 1024, augmenter la longueur de la file d'attente à 8192 peut accueillir davantage de connexions réseau en attente de connexions.
  • net.ipv4.tcp_max_tw_buckets= 5000 signifie que le système maintient le nombre maximum de TIME_WAIT en même temps. Si ce nombre est dépassé, TIME_WAIT sera immédiatement effacé et un message d'avertissement sera imprimé. La valeur par défaut est 180 000, remplacez-la par 5 000. Ce paramètre peut contrôler le nombre maximum de TIME_WAIT, tant qu'il est dépassé. Description des autres paramètres TCP du noyau
  • net.ipv4.tcp_max_syn_backlog= 65536 La valeur maximale des demandes de connexion enregistrées qui n'ont pas encore reçu d'informations de confirmation du client. Pour les systèmes dotés de 128 Mo de mémoire, la valeur par défaut est 1 024 et pour les systèmes dotés de petite mémoire, elle est de 128.
  • net.core.netdev_max_backlog= 32768 Le nombre maximum de paquets autorisés à être mis en file d'attente lorsque chaque interface réseau reçoit des paquets plus rapidement que le noyau ne peut les traiter.
  • net.core.somaxconn= 32768 Par exemple, le backlog de la fonction d'écoute dans une application Web limitera le net.core.somaxconn de nos paramètres de noyau à 128 par défaut, et le NGX_LISTEN_BACKLOG défini par nginx par défaut à 511 , il est donc nécessaire d'ajuster cette valeur.
  • net.core.wmem_default= 8388608
  • net.core.rmem_default= 8388608
  • net.core.rmem_max= 16777216 #Tampon de lecture de socket maximum, valeur d'optimisation de référence 8732 00
  • net .core.wmem_max= 16777216 #Tampon d'écriture de socket maximum, valeur d'optimisation de référence : 873200
  • net.ipv4.tcp_timestsmps= 0 L'horodatage peut éviter l'enroulement du numéro de séquence. Une liaison à 1 Gbit/s rencontrera certainement des numéros de séquence qui ont été utilisés auparavant. L'horodatage permet au noyau d'accepter de tels paquets « anormaux ». Il doit être désactivé ici.
  • net.ipv4.tcp_synack_retries= 2 Afin d'ouvrir une connexion avec le homologue, le noyau doit envoyer un SYN avec un ACK en réponse au SYN précédent. Il s’agit de la deuxième poignée de main de la soi-disant poignée de main à trois. Ce paramètre détermine le nombre de paquets SYN+ACK envoyés par le noyau avant d'abandonner la connexion.
  • net.ipv4.tcp_syn_retries= 2 Le nombre de paquets SYN envoyés avant que le noyau n'abandonne l'établissement de la connexion.
  • #net.ipv4.tcp_tw_len= 1
  • net.ipv4.tcp_tw_reuse= 1 Activer la réutilisation. Permet de réutiliser les sockets TIME-WAIT pour de nouvelles connexions TCP.
  • net.ipv4.tcp_wmem= 8192 436600 873200 Tampon d'écriture TCP, valeur d'optimisation de référence : 8192 436600 873200
  • net.ipv4.tcp_rmem = 32768 436600 200 tampon de lecture TCP, valeur d'optimisation de référence : 32768 436600 873200
  • net.ipv4.tcp_mem= 94500000 91500000 92700000 Il y a aussi 3 valeurs, ce qui signifie :
  • net.ipv4.tcp_mem[0] : En dessous de cette valeur, TCP n'a aucune pression mémoire.
  • net.ipv4.tcp_mem[1] : A cette valeur, entrez dans l'étape de pression mémoire.
  • net.ipv4.tcp_mem[2] : Au-dessus de cette valeur, TCP refuse d'allouer le socket. Les unités de mémoire mentionnées ci-dessus sont des pages et non des octets. La valeur d'optimisation de référence est : 7864321048576 1572864
  • net.ipv4.tcp_max_orphans= 3276800 Le nombre maximum de sockets TCP dans le système qui ne sont associés à aucun descripteur de fichier utilisateur. Si ce nombre est dépassé, la connexion sera immédiatement réinitialisée et un message d'avertissement sera imprimé. Cette limite sert uniquement à empêcher les attaques DoS simples. Vous ne pouvez pas trop vous y fier ou réduire artificiellement cette valeur. Vous devez augmenter cette valeur (si vous augmentez la mémoire).
  • net.ipv4.tcp_fin_timeout= 30 Si le socket doit être fermé par l'extrémité locale, ce paramètre détermine combien de temps il reste dans l'état FIN-WAIT-2. L'homologue peut commettre des erreurs et ne jamais fermer la connexion, voire même planter de manière inattendue. La valeur par défaut est de 60 secondes. La valeur habituelle pour le noyau 2.2 est de 180 secondes. Vous pouvez appuyer sur ce paramètre, mais rappelez-vous que même si votre machine est un serveur WEB peu chargé, il existe un risque de débordement de mémoire dû à un grand nombre de sockets morts. 2 est moins dangereux que FIN-WAIT-1 car il ne peut consommer que jusqu'à 1,5 Ko de mémoire, mais leur période de survie est plus longue.

Cela implique également un problème d'algorithme de congestion TCP. Vous pouvez utiliser la commande suivante pour afficher le module de contrôle de l'algorithme de congestion fourni par cette machine :

  • sysctl net.ipv4.tcp_available_congestion_control

Pour plusieurs algorithmes Pour analyse. , veuillez vous référer à ce qui suit pour plus de détails : avantages et inconvénients, environnement applicable et analyse des performances de l'algorithme de contrôle de congestion TCP. Par exemple, vous pouvez essayer hybla pour les délais élevés et l'algorithme htcp pour les délais moyens, etc.

Si vous souhaitez définir l'algorithme de congestion TCP sur hybla net.ipv4.tcp_congestion_control=hybla

De plus, pour les versions du noyau supérieures à 3.7.1, nous pouvons activer tcp_fastopen : net.ipv4.tcp_fastopen= 3

IO Mécanisme de distribution d'événements

Pour activer les connexions TCP à haute concurrence sous Linux, vous devez confirmer si l'application utilise la technologie d'E/S réseau appropriée et le mécanisme de répartition des événements d'E/S. Les technologies d'E/S disponibles sont les E/S synchrones, les E/S synchrones non bloquantes et les E/S asynchrones. Dans le cas d'une concurrence TCP élevée, si des E/S synchrones sont utilisées, cela bloquera sérieusement le fonctionnement du programme à moins qu'un thread ne soit créé pour les E/S par connexion TCP. Cependant, un trop grand nombre de threads entraînera une surcharge énorme en raison de la planification des threads du système. Par conséquent, il n’est pas conseillé d’utiliser des E/S synchrones dans des situations de concurrence TCP élevée. Dans ce cas, vous pouvez envisager d’utiliser des E/S synchrones non bloquantes ou des E/S asynchrones. Les technologies d'E/S synchrones non bloquantes incluent l'utilisation de select(), poll(), epoll et d'autres mécanismes. La technologie des E/S asynchrones consiste à utiliser AIO.

Du point de vue du mécanisme de répartition des événements d'E/S, il est inapproprié d'utiliser select() car il prend en charge un nombre limité de connexions simultanées (généralement dans les 1024). Si l'on considère les performances, poll() est également inapproprié. Bien qu'il puisse prendre en charge un nombre plus élevé de simultanéités TCP, en raison de son mécanisme de « sondage », lorsque le nombre de simultanéités est élevé, son efficacité opérationnelle est assez faible, et il peut y en avoir. Les événements d'E/S sont répartis de manière inégale, provoquant une « famine » d'E/S sur certaines connexions TCP. Si vous utilisez epoll ou AIO, il n'y a pas de problème ci-dessus (la première implémentation de la technologie AIO dans le noyau Linux a été réalisée en créant un thread dans le noyau pour chaque requête d'E/S. Ce mécanisme d'implémentation fonctionne bien dans le cas d'un nombre élevé de requêtes simultanées. Connexions TCP. Il existe en fait de sérieux problèmes de performances avec son utilisation, mais dans le dernier noyau Linux, l'implémentation d'AIO a été améliorée.

En résumé, lors du développement d'applications Linux prenant en charge des connexions TCP simultanées élevées, vous devez essayer d'utiliser la technologie epoll ou AIO pour obtenir un contrôle d'E/S sur les connexions TCP simultanées. Cela améliorera la capacité du programme à gérer des connexions TCP simultanées élevées. fournit des garanties d'E/S efficaces.

Après une telle configuration optimisée, la capacité de traitement simultané TCP du serveur sera considérablement améliorée. La configuration ci-dessus est à titre de référence uniquement. Si elle est utilisée dans un environnement de production, veuillez observer et ajuster en fonction de votre situation réelle.

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:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer