Maison >Opération et maintenance >Sécurité >Comment résoudre les défauts Ulimit
J'ai récemment rencontré un problème très intéressant. Il existe un groupe de HAProxy qui rencontre des problèmes fréquents. Connectez-vous au serveur et vérifiez le processeur, la mémoire, le réseau et les E/S. Il a finalement été découvert qu'il y avait plus de 60 000 connexions dans l'état TIME_WAIT de la machine. L'état
TIME_WAIT apparaît généralement sur les machines proxy telles que HAProxy et Nginx, principalement en raison d'arrêts actifs fréquents. En modifiant les paramètres de réutilisation et de recyclage, le problème peut être résolu relativement rapidement.
Les statistiques de l'état du réseau peuvent être calculées à l'aide de la commande suivante.
netstat -ant|awk '/^tcp/ {++S[$NF]} END {for(a in S) print (a,S[a])}' ESTABLISHED 70 FIN_WAIT2 30 CLOSING 33 TIME_WAIT 65520
Il n'y a rien de magique là-dedans, mais le nombre 65535 est vraiment trop sensible. Cela aurait dû déclencher une sorte de limite supérieure.
Ce qui nous rend encore plus perplexes, c'est : pourquoi le service est-il indisponible lorsque les connexions dans l'état TIME_WAIT n'atteignent que 65535 ?
Les affirmations de millions de connexions par machine ne font-elles que se vanter ?
65535, qui signifie égal à 2 à la puissance 16 moins un, est un nombre magique. Laissant ce petit nombre de côté pour le moment, comprenons d'abord quelle capacité de connexion prend en charge Linux.
1. Combien de connexions Linux peut-il prendre en charge ?
La réponse est innombrable. Mais il n’y a que 65 535 ports.
Pourquoi n'y a-t-il que 65535 ports ?
Les protocoles TCP et UDP utilisent 16 bits au début pour stocker respectivement le numéro de port source et le numéro de port de destination. Ceci est basé sur des raisons historiques. Malheureusement, cette valeur est de type short et la taille est également de 2^16-1.
Les normes immuables causées par des raisons historiques sont si profondément enracinées.
Alors, combien de connexions Linux peut-il prendre en charge ? La réponse est innombrable.
Prenons nginx comme exemple, nous le surveillons sur le port 80. À l’heure actuelle, la machine A se connecte à Nginx et peut initier jusqu’à 60 000 connexions longues. Si la machine B se connecte à Nginx, elle peut également initier 60 000 connexions multiples. En effet, la détermination d'une connexion est déterminée par src et dst.
L'idée selon laquelle Linux ne peut accepter que 65 535 connexions ne peut être considérée que comme une hypothèse très superficielle.
65535 ports, il est peut-être trop petit pour vous en tant que testeur de stress. Mais pour les serveurs, c'est largement suffisant.
2. Comment prendre en charge des millions de connexions ?
Comme vous pouvez le voir ci-dessus, il n'y a pas de limite au nombre de connexions. Mais Linux dispose d'un autre niveau de protection, à savoir le nombre de descripteurs de fichiers. Les éléments visualisés via la commande lsof sont ce qu'on appelle des descripteurs de fichiers.
Intéressons-nous d'abord à l'affichage de quelques commandes.
ulmit, affiche le nombre de descripteurs de fichiers que chaque processus peut occuper.
ulimit -n 65535
file-max, affiche le nombre total de descripteurs de fichiers que le système d'exploitation peut occuper, pour tous les processus.
cat /proc/sys/fs/file-max 766722
file-nr, affiche le nombre de poignées actuellement utilisées et le nombre total de poignées. Peut être utilisé pour la surveillance.
cat /proc/sys/fs/file-nr 1824 0 766722
Afin de prendre en charge des millions de connexions, les handles au niveau du système d'exploitation et au niveau du processus doivent être publiés. En d’autres termes, l’affichage de ulimit et file-max doit être supérieur à un million.
3. Comment le définir ?
Bien qu'une solution couramment utilisée soit ulimit pour définir le nombre de poignées de processus, je vous le recommande fortement. Seuls les processus démarrés dans le même shell seront affectés par le paramètre ulimit, sans autre raison. Si vous ouvrez un autre shell ou redémarrez la machine, les modifications ulimit disparaîtront. Il s'agit de la méthode suivante :
ulimit -n 1000000
La bonne méthode est de modifier le fichier /etc/security/limits.conf. Par exemple, le contenu suivant.
root soft nofile 1000000 root hard nofile 1000000 * soft nofile 1000000 * hard nofile 1000000
Vous pouvez voir que nous pouvons modifier le nombre de handles pour un utilisateur spécifique. Ceci est souvent rencontré lors de l’installation d’applications telles que es.
es - nofile 65535
En utilisant cette méthode, vous devez toujours ouvrir un nouveau shell pour fonctionner. Cette commande ne prendra effet ni dans le shell modifié ni dans le shell avant modification. xjjdog a rencontré plusieurs cas où des problèmes persistaient malgré la levée des restrictions.
Affichez le fichier mappé en mémoire du processus pour déterminer si ces modifications ont pris effet. Par exemple, dans la commande "cat /proc/180323/limits", des informations détaillées seront affichées.
Cette valeur n'est pas définie aussi haut que vous le souhaitez. Sa limite supérieure de taille est déterminée par nr_open. Pour augmenter la taille, modifiez la valeur de fs.nr_open dans /ect/sysct.conf.
cat /proc/sys/fs/nr_open 1048576
Si vous souhaitez modifier le paramètre file-max, il est recommandé d'ajouter le contenu suivant au fichier /etc/sysctl.conf. Il y en a plus de 6 millions !
fs.file-max = 6553560
Lorsque le nombre de fichiers dépasse, l'erreur noyau : VFS : limite maximale de fichier 65535 atteinte sera signalée.
Pour résumer.
Même si Linux ouvre un port, il peut accepter un nombre massif de connexions. La limite supérieure de ces connexions est limitée par le nombre de descripteurs de fichiers dans un seul processus et par le nombre de descripteurs de fichiers dans le système d'exploitation, c'est-à-dire ulimit et file-max.
Afin de conserver les modifications de paramètres, nous avons tendance à écrire les modifications dans des fichiers. La limite de descripteurs de fichiers du processus peut être placée dans /etc/security/limits.conf, et sa limite supérieure est limitée par fs.nr_open ; la limite de descripteurs de fichiers du système d'exploitation peut être placée dans /etc/sysctl.conf ; déposer. Enfin, assurez-vous de vérifier le fichier /proc/$id/limits pour confirmer si la modification a pris effet au cours du processus.
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!