Comment fonctionne le rechargement de NGINX ? Pourquoi NGINX ne recharge-t-il pas à chaud ?
Wei Liu
September 30, 2022
J'ai récemment remarqué un post sur Reddit qui disait "Pourquoi NGINX ne supporte pas le rechargement à chaud ?". Étrangement, NGINX, le plus grand serveur web au monde, ne supporte pas le rechargement à chaud ? Cela signifie-t-il que nous utilisons tous nginx -s reload
incorrectement ? Avec cette question, vérifions comment fonctionne le rechargement de NGINX.
Qu'est-ce que NGINX
NGINX est un serveur web open-source multiplateforme développé en langage C. Selon les statistiques, parmi les 1000 sites web ayant le plus de trafic, plus de 40 % d'entre eux utilisent NGINX pour gérer les énormes demandes.
Pourquoi NGINX est-il si populaire
Quels avantages NGINX possède-t-il pour surpasser les autres serveurs web et maintenir un taux d'utilisation élevé ?
La principale raison est que NGINX est conçu pour gérer les problèmes de haute concurrence. Par conséquent, NGINX peut fournir un service stable et efficace tout en gérant d'énormes demandes concurrentes. De plus, comparé à ses concurrents de la même époque, comme Apache et Tomcat, NGINX possède de nombreuses conceptions extraordinaires comme une architecture événementielle avancée, un mécanisme entièrement asynchrone pour gérer les E/S réseau, et un système de gestion de mémoire extrêmement efficace. Ces conceptions remarquables aident NGINX à utiliser entièrement les ressources matérielles des serveurs et font de NGINX un synonyme de serveur web.
En plus de ce qui précède, il y a d'autres raisons comme :
- Une conception hautement modulaire permet à NGINX de posséder de nombreux modules officiels et tiers riches en fonctionnalités.
- La licence BSD la plus libre incite les développeurs à contribuer volontairement à NGINX.
- Le support du rechargement à chaud permet à NGINX de fournir des services 24/7.
Parmi ces raisons, le rechargement à chaud est notre sujet principal aujourd'hui.
Que fait le rechargement à chaud
Qu'attendons-nous du rechargement à chaud ? Premièrement, je pense que les utilisateurs côté client ne devraient pas être conscients du rechargement du serveur. Deuxièmement, les serveurs ou les services en amont devraient réaliser un chargement dynamique et gérer toutes les demandes des utilisateurs avec succès sans temps d'arrêt.
Dans quelles circonstances avons-nous besoin du rechargement à chaud ? À l'ère du Cloud Native, les microservices sont devenus si populaires que de plus en plus de scénarios d'application nécessitent des modifications fréquentes côté serveur. Ces modifications, comme la mise en ligne/hors ligne du proxy inverse de domaine, les changements d'adresse en amont, et les modifications de liste blanche/noire d'IP, sont liées au rechargement à chaud.
Alors, comment NGINX réalise-t-il le rechargement à chaud ?
Le principe du rechargement à chaud de NGINX
Lorsque nous exécutons la commande de rechargement à chaud nginx -s reload
, elle envoie un signal HUP au processus maître de NGINX. Lorsque le processus maître reçoit le signal HUP, il ouvre les ports d'écoute séquentiellement et démarre un nouveau processus worker. Par conséquent, deux processus worker (ancien et nouveau) existeront simultanément. Après que le nouveau processus worker entre en jeu, le processus maître enverra un signal QUIT à l'ancien processus worker pour l'arrêter gracieusement. Lorsque l'ancien processus worker reçoit le signal QUIT, il fermera d'abord le gestionnaire d'écoute. Maintenant, toutes les nouvelles connexions entreront uniquement dans le nouveau processus worker, et le serveur arrêtera l'ancien processus une fois qu'il aura traité toutes les connexions restantes.
En théorie, le rechargement à chaud de NGINX pourrait-il parfaitement répondre à nos exigences ? Malheureusement, la réponse est non. Alors, quels sont les inconvénients du rechargement à chaud de NGINX ?
Le rechargement de NGINX provoque des temps d'arrêt
-
Un rechargement à chaud trop fréquent rendrait les connexions instables et entraînerait une perte de données métier.
Lorsque NGINX exécute la commande de rechargement, l'ancien processus worker continuera à traiter les connexions existantes et se déconnectera automatiquement une fois qu'il aura traité toutes les demandes restantes. Cependant, si le client n'a pas traité toutes les demandes, il perdra définitivement les données métier des demandes restantes. Bien sûr, cela attirerait l'attention des utilisateurs côté client.
-
Dans certaines circonstances, le temps de recyclage de l'ancien processus worker est si long qu'il affecte les activités normales.
Par exemple, lorsque nous proxions le protocole WebSocket, nous ne pouvons pas savoir si une demande a été traitée car NGINX ne parse pas la trame d'en-tête. Donc, même si le processus worker reçoit la commande d'arrêt du processus maître, il ne peut pas quitter tant que ces connexions ne génèrent pas d'exceptions, ne dépassent pas le délai ou ne se déconnectent pas.
Voici un autre exemple, lorsque NGINX agit comme proxy inverse pour TCP et UDP, il ne peut pas savoir à quelle fréquence une demande est effectuée avant d'être finalement arrêtée.
Par conséquent, l'ancien processus worker prend généralement beaucoup de temps, en particulier dans des industries comme la diffusion en direct, les médias et la reconnaissance vocale. Parfois, le temps de recyclage de l'ancien processus worker peut atteindre une demi-heure ou même plus. En attendant, si les utilisateurs rechargent fréquemment le serveur, cela créera de nombreux processus en cours d'arrêt et finira par entraîner un OOM de NGINX, ce qui pourrait sérieusement affecter les activités.
# toujours présent dans l'ancien processus worker :
nobody 6246 6241 0 10:51 ? 00:00:00 nginx: worker process
nobody 6247 6241 0 10:51 ? 00:00:00 nginx: worker process
nobody 6247 6241 0 10:51 ? 00:00:00 nginx: worker process
nobody 6248 6241 0 10:51 ? 00:00:00 nginx: worker process
nobody 6249 6241 0 10:51 ? 00:00:00 nginx: worker process
nobody 7995 10419 0 10:30 ? 00:20:37 nginx: worker process is shutting down <= ici
nobody 7995 10419 0 10:30 ? 00:20:37 nginx: worker process is shutting down
nobody 7996 10419 0 10:30 ? 00:20:37 nginx: worker process is shutting down
En résumé, nous pourrions réaliser le rechargement à chaud en exécutant nginx -s reload
, ce qui était suffisant dans le passé. Cependant, le développement rapide des microservices et du Cloud Native fait que cette solution ne répond plus aux exigences des utilisateurs.
Si la fréquence de mise à jour de votre activité est hebdomadaire ou quotidienne, alors ce NGINX rechargement pourrait encore satisfaire vos besoins. Cependant, que se passe-t-il si la fréquence de mise à jour devient horaire ou par minute ? Par exemple, supposons que vous ayez 100 serveurs NGINX, et qu'il se recharge une fois par heure, alors il devra se recharger 2400 fois par jour ; Si le serveur se recharge par minute, alors il devra se recharger 8 640 000 fois par jour, ce qui est inacceptable.
Nous avons besoin d'une solution sans changement de processus, et qui pourrait également réaliser des mises à jour de contenu immédiates.
Rechargement à chaud qui prend effet immédiatement en mémoire
Lorsque Apache APISIX est né, il a été conçu pour résoudre le problème de rechargement à chaud de NGINX. APISIX est développé sur la base des piles technologiques de NGINX et Lua, et c'est une passerelle API microservices cloud-native, haute performance et entièrement dynamique qui utilise etcd comme centre de configuration principal. Il n'est pas nécessaire de redémarrer le serveur pour recharger la nouvelle configuration du serveur, ce qui signifie que tout changement de services en amont, de routes ou de plugins ne nécessitera pas de redémarrage du serveur. Mais comment APISIX pourrait-il éliminer les limitations de NGINX pour réaliser un rechargement à chaud parfait basé sur le fait qu'APISIX est développé sur la pile technologique de NGINX ?
Tout d'abord, voyons l'architecture logicielle d'Apache APISIX :
APISIX pourrait réaliser le rechargement à chaud parfait car il place toutes les configurations dans le cœur d'APISIX et le runtime des plugins afin qu'ils puissent utiliser les affectations dynamiques. Par exemple, lorsque NGINX doit configurer des paramètres dans les fichiers de configuration, chaque modification ne prend effet qu'après un rechargement. Pour configurer dynamiquement les routes, Apache APISIX ne configure qu'un seul serveur spécifique avec un seul emplacement. Nous devons utiliser cet emplacement comme point d'entrée principal afin que toutes les demandes passent d'abord par lui, puis le cœur d'APISIX affectera dynamiquement des services en amont spécifiques pour elles. Le module de route d'Apache APISIX pourrait supporter l'ajout/suppression, la modification et la suppression de routes pendant que le serveur fonctionne. En d'autres termes, il pourrait réaliser un rechargement dynamique. Aucun de ces changements n'attirerait l'attention des utilisateurs et n'affecterait les activités normales.
Maintenant, introduisons un scénario classique ; par exemple, si nous voulons ajouter un proxy inverse pour un nouveau domaine, nous devons simplement créer un service en amont dans APISIX et ajouter une nouvelle route. NGINX n'a pas besoin de redémarrer pendant ce processus. Voici un autre exemple pour le système de plugins : APISIX pourrait utiliser un plugin de restriction d'IP pour réaliser la fonctionnalité de liste blanche/noire d'IP. Toutes ces mises à jour de fonctionnalités sont dynamiques et ne nécessitent pas de redémarrage du serveur. Grâce à etcd, la stratégie de configuration pourrait réaliser des mises à jour instantanées à l'aide d'add-ons, et toutes les configurations pourraient prendre effet immédiatement et fournir la meilleure expérience utilisateur.
Conclusion
Le rechargement à chaud de NGINX aurait un ancien et un nouveau processus worker dans certaines circonstances, ce qui entraîne un gaspillage supplémentaire de ressources. De plus, un rechargement à chaud trop fréquent pourrait entraîner une légère chance de perte totale de données métier. Dans le contexte du Cloud Native et des microservices, les mises à jour de services deviennent de plus en plus fréquentes, et la stratégie de gestion des API varie également, ce qui conduit à de nouvelles exigences pour le rechargement à chaud.
Le rechargement à chaud de NGINX ne satisfait plus les exigences métier. Il est temps de passer à Apache APISIX, une passerelle API avec une stratégie de rechargement à chaud plus avancée à l'ère du Cloud Native. De plus, après être passé à APISIX, les utilisateurs pourraient avoir une gestion dynamique et uniforme des services API, et cela pourrait considérablement améliorer l'efficacité de la gestion.