connexion
Dans Nginx, la connexion est l'encapsulation de la connexion TCP, y compris le socket connecté et les événements de lecture. , écrire des événements. Grâce à la connexion encapsulée par Nginx, nous pouvons facilement utiliser Nginx pour gérer les questions liées à la connexion, telles que l'établissement de connexions, l'envoi et la réception de données, etc. Peut également être utilisé comme serveur de messagerie. Bien entendu, en utilisant la connexion fournie par Nginx, nous pouvons gérer n’importe quel service backend.
En combinaison avec le cycle de vie d'une connexion TCP, jetons un coup d'œil à la façon dont Nginx gère une connexion. Tout d'abord, lorsque Nginx démarre, il analysera le fichier de configuration pour obtenir le port et l'adresse IP qui doivent être surveillés. Ensuite, dans le processus maître Nginx, initialisez d'abord le socket de surveillance (créez le socket, définissez l'adresse). et d'autres options, se lier au port d'adresse IP spécifié, écouter à nouveau), puis débourser plusieurs processus enfants, puis les processus enfants seront en compétition pour accepter de nouvelles connexions.
À ce stade, le client peut initier une connexion à Nginx.
Lorsque le client et le serveur établissent une connexion via une négociation à trois, un sous-processus de Nginx acceptera avec succès, obtiendra le socket de la connexion établie, puis créera une encapsulation Nginx de la connexion, à savoir Structure ngx_connection_t.
Ensuite, définissez les fonctions de traitement des événements de lecture et d'écriture et ajoutez des événements de lecture et d'écriture pour échanger des données avec le client. Enfin, Nginx ou le client ferme activement la connexion. À ce stade, une connexion prend fin.
Bien entendu, Nginx peut également être utilisé comme client pour demander des données à d'autres serveurs (comme le module amont). À ce stade, les connexions créées avec d'autres serveurs sont également encapsulées dans ngx_connection_t.
En tant que client, Nginx obtient d'abord une structure ngx_connection_t, puis crée un socket et définit les attributs du socket (tels que non bloquant). Ajoutez ensuite des événements de lecture et d'écriture, appelez connect/read/write pour appeler la connexion, et enfin fermez la connexion et relâchez ngx_connection_t.
Dans Nginx, chaque processus a une limite maximale sur le nombre de connexions, qui est différente de la limite du système sur fd. Dans le système d'exploitation, grâce à ulimit -n, nous pouvons obtenir le nombre maximum de fds qu'un processus peut ouvrir, c'est-à-dire aucun fichier. Parce que chaque connexion socket occupera un fd, cela limitera également le nombre maximum de connexions de notre processus. Bien sûr, cela affectera également directement le nombre maximum de simultanéités que notre programme peut prendre en charge. Lorsque le fd est épuisé, la création d'un socket échouera.
Nginx définit le nombre maximum de connexions prises en charge par chaque processus en définissant worker_connectons. Si cette valeur est supérieure à nofile, alors le nombre maximum réel de connexions est nofile et Nginx vous avertira.
Nginx est géré via un pool de connexions lors de sa mise en œuvre. Chaque processus de travail dispose d'un pool de connexions indépendant, et la taille du pool de connexions est worker_connections. Ce qui est enregistré ici dans le pool de connexions n'est pas réellement une connexion réelle, c'est juste un tableau de structure ngx_connection_t de taille worker_connections.
De plus, Nginx enregistrera tous les ngx_connection_t gratuits via une liste chaînée free_connections. Chaque fois qu'une connexion est obtenue, il en obtiendra une dans la liste de connexions gratuites. Après l'avoir utilisée, elle sera remise dans la connexion gratuite. liste.
Ici, beaucoup de gens comprendront mal la signification du paramètre worker_connections, pensant que cette valeur est la valeur maximale de la connexion que Nginx peut établir. En fait, cette valeur représente le nombre maximum de connexions pouvant être établies par chaque processus de travail. Par conséquent, le nombre maximum de connexions pouvant être établies par un Nginx doit être worker_connections * work_processes.
Bien sûr, nous parlons ici du nombre maximum de connexions. Pour les requêtes HTTP pour les ressources locales, le nombre maximum de simultanéités pouvant être prises en charge est worker_connections * worker_processes. proxy, le nombre maximum de simultanéités doit être work_connections * work_processes/2.
Car en tant que serveur proxy inverse, chaque connexion simultanée établira une connexion avec le client et une connexion avec le service back-end, qui occupera deux connexions.
Eh bien, comme nous l'avons déjà dit, après la connexion d'un client, plusieurs processus inactifs se disputeront la connexion. Il est facile de voir que cette concurrence entraînera une injustice si un processus est accepté. Il y a plus d'opportunités, et ses connexions inactives seront rapidement utilisées. Si un certain contrôle n'est pas effectué à l'avance, lorsqu'une nouvelle connexion TCP est acceptée, car il ne peut pas obtenir une connexion inactive et ne peut pas transférer cette connexion à d'autres processus, cela finira par le faire. la connexion TCP ne peut pas être traitée et est terminée.
C'est évidemment injuste. Certains processus ont des connexions libres mais n'ont aucune chance de les traiter. Certains processus suppriment artificiellement les connexions parce qu'ils n'ont pas de connexions libres. Alors, comment résoudre ce problème ?
Tout d'abord, le traitement Nginx doit d'abord activer l'option accept_mutex. À ce stade, seul le processus qui a obtenu accept_mutex ajoutera l'événement accept. En d'autres termes, Nginx contrôlera si le processus ajoute l'acceptation. événement.
Nginx utilise une variable appelée ngx_accept_disabled pour contrôler s'il faut concourir pour le verrou accept_mutex.
Dans le premier morceau de code, calculez la valeur de ngx_accept_disabled. Cette valeur correspond à un huitième du nombre total de connexions dans un seul processus Nginx. Soustrayez le nombre restant de connexions inactives. Le ngx_accept_disabled résultant a un. pattern , lorsque le nombre de connexions restantes est inférieur à un huitième du nombre total de connexions, sa valeur est supérieure à 0, et plus le nombre de connexions restantes est petit, plus cette valeur est grande.
Regardez le deuxième morceau de code. Lorsque ngx_accept_disabled est supérieur à 0, il n'essaiera pas d'acquérir le verrou accept_mutex et décrémentera ngx_accept_disabled de 1. Par conséquent, chaque fois qu'il sera exécuté ici, il sera décrémenté de 1. 1 jusqu'à ce qu'il soit inférieur à 0.
Ne pas acquérir le verrou accept_mutex équivaut à renoncer à la possibilité d'obtenir la connexion. On voit clairement que lorsqu'il y a moins de connexions libres, plus ngx_accept_disable est grand, donc plus d'opportunités sont données, donc. que d'autres processus Les chances d'acquérir le verrou sont également plus grandes.
Si vous n'acceptez pas, votre propre connexion sera contrôlée et le pool de connexions des autres processus sera utilisé de cette manière, Nginx contrôle l'équilibre des connexions entre plusieurs processus.
ngx_accept_disabled = ngx_cycle->connection_n / 8 - ngx_cycle->free_connection_n; if (ngx_accept_disabled > 0) { ngx_accept_disabled--; } else { if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) { return; } if (ngx_accept_mutex_held) { flags |= NGX_POST_EVENTS; } else { if (timer == NGX_TIMER_INFINITE || timer > ngx_accept_mutex_delay) { timer = ngx_accept_mutex_delay; } } }
La connexion sera présentée ici en premier. Il vous suffit de savoir quelle est la connexion dans Nginx, et la connexion est une utilisation relativement avancée.
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!