Erreur HTTP 503. Service non disponible: un cas dans la prise en charge de l'hébergement

Le travail de support d'hébergement est fondamentalement du même type, la plupart des demandes des clients sont résolues selon un schéma bien développé, mais parfois vous devez toujours faire face à des problèmes non triviaux. Ensuite, la tâche principale de l'ingénieur est de trouver celui - le seul chemin correct qui mènera à sa solution. Dans cet article, je veux parler de la façon dont nous avons rencontré l'erreur flottante "HTTP Error 503. Service Unavailable" sur notre hébergement partagé, comment nous avons essayé de l'attraper, de le diagnostiquer et d'obtenir une fin inattendue.



Début



L'hébergement fournit aux utilisateurs une pile Linux + Apache + Mysql + PHP typique et un wrapper de gestion. Dans notre cas, il s'agit de l'activité ISP Manager 5 basée sur Centos 7 avec conversion vers CloudLinux. Du côté administratif, CloudLinux fournit des outils de gestion des limites, ainsi qu'un sélecteur PHP avec différents modes de fonctionnement (CGI, FastCGI, LSAPI).



Cette fois, un client nous a contacté avec le problème suivant. Son site sur le moteur Wordpress commençait périodiquement à donner 503 erreurs, dont il nous a informés.



Les codes de réponse commençant par 50x font référence aux problèmes côté serveur. Ceux-ci peuvent être des problèmes à la fois du site lui-même et du serveur Web qui les dessert.



Situations typiques dans lesquelles nous recevons les erreurs suivantes:



  • 500 Erreur interne du serveur - elle est souvent associée soit à des erreurs de syntaxe dans le code du site, soit à des bibliothèques manquantes / version PHP non prise en charge. Il peut également y avoir des problèmes de connexion à la base de données du site ou des autorisations incorrectes sur les fichiers / répertoires
  • 502 Bad Gateway - par exemple, si Nginx fait référence au mauvais port de serveur Web Apache ou si le processus Apache cesse de fonctionner pour une raison quelconque
  • 504 Gateway Timeout - la réponse d'Apache n'a pas été reçue dans le délai spécifié dans la configuration du serveur Web
  • 508 La limite des ressources est atteinte - la limite des ressources allouées à l'utilisateur a été dépassée


Cette liste ne contient que quelques-uns des cas les plus courants. Il convient également de noter que lorsque les limites sont dépassées, l'utilisateur peut recevoir à la fois des erreurs 500 et 503.



Lors du diagnostic de ces erreurs, la première étape consiste à vérifier les journaux du serveur Web. Cela suffit généralement pour identifier le coupable et résoudre le problème.



Concernant l'erreur 503 dans notre cas, nous avons vu une entrée dans les journaux:

[lsapi: error] [pid 49817] [client xxxx: 6801] [host XXX.XX] Erreur lors de l'envoi de la requête (GET /index.php HTTP / 1.0); uri (/index.php) content-length (0): ReceiveAckHdr: rien à lire depuis le backend (LVE ID 8514), consultez docs.cloudlinux.com/mod_lsapi_troubleshooting.html
En se basant uniquement sur ce journal, il n'a pas été possible de déterminer quel pourrait être le problème.



Diagnostic primaire



Dans un premier temps, nous avons vérifié les statistiques des utilisateurs dépassant les limites. Des excès mineurs ont été enregistrés les jours précédents, mais les erreurs dans les journaux étaient fraîches, de plus, elles sont apparues dans le journal à des intervalles de une à plusieurs minutes.



Nous avons également étudié les recommandations CloudLinux en utilisant le lien fourni dans les journaux d'erreurs.

La modification des paramètres n'a donné aucun résultat.



Le site a utilisé une base de données sur un serveur Mysql 5.7 qui s'exécute sur le même serveur dans un conteneur Docker. Les journaux de conteneur contenaient des messages:



[Note] Aborted connection 555 to db: 'dbname' user: 'username' host: 'x.x.x.x' (Got an error reading communication packets)


Parmi ces messages figuraient des messages sur l'interruption de la connexion du site sous enquête. Cela a supposé que la connexion au SGBD n'était pas effectuée correctement. Pour le vérifier, nous avons déployé une copie du site sur un domaine de test, converti la base de données du site en version native Centos 7 du SGBD 5.5.65-MariaDB. Sur le site de test, plusieurs centaines de requêtes ont été exécutées à l'aide de l'utilitaire curl. L'erreur n'a pas pu être reproduite. Mais ce résultat était préliminaire et après la conversion de la base de données sur le site de production, le problème persistait.



Ainsi, le problème de connexion incorrecte au SGBD a été éliminé.



La suggestion suivante était de vérifier s'il y avait des problèmes avec le site lui-même. Pour ce faire, nous avons mis en place un serveur virtuel séparé, sur lequel nous avons soulevé l'environnement le plus similaire. La seule différence significative est l'absence de CloudLinux. Le problème n'a pas pu être reproduit sur le serveur de test. Nous avons donc déterminé que tout est en ordre dans le code du site. Cependant, nous avons essayé de désactiver les plugins Wordpress de la même manière, mais le problème a persisté.



En conséquence, nous sommes arrivés à la conclusion que le problème se situe au niveau de notre hébergement.



Après avoir analysé les journaux d'autres sites, il a été constaté que le problème est observé sur beaucoup d'entre eux. Environ 100 pièces. au moment de la vérification:



/var/www/httpd-logs# grep -Rl "ReceiveAckHdr: nothing to read from backend" ./ | wc -l
99


Lors des tests, nous avons constaté que le CMS propre fraîchement installé Wordpress donne également périodiquement l'erreur 503.



Environ 2 mois avant cela, nous avons effectué des travaux de modernisation du serveur, en particulier, nous avons changé le mode de fonctionnement Apache de Worker à Prefork, afin de pouvoir utiliser PHP dans LSAPI au lieu de CGI lent. Il y avait une hypothèse que cela pourrait affecter, ou que certains paramètres Apache supplémentaires sont nécessaires, mais nous ne pouvions pas retourner le mode Worker. Lors du changement de mode de fonctionnement d'Apache, toutes les configurations du site sont modifiées, le processus n'est pas rapide et tout ne peut pas se passer sans problème.



La correction des paramètres Apache n'a pas non plus donné le résultat souhaité.



En cours de route, nous avons recherché des problèmes similaires dans les moteurs de recherche. Sur l'un des forums, les participants ont fait valoir que l'hébergeur a un problème et doit être changé si le problème n'est pas résolu. Cela ne semble pas très optimiste lorsque vous êtes de l'autre côté, mais vous pouvez comprendre le client. Pourquoi a-t-il besoin d'un hébergement non fonctionnel.



A ce stade, nous avons collecté les informations disponibles et les résultats des travaux effectués. Ils ont été contactés pour soutenir CloudLinux.



Diagnostics détaillés



Pendant plusieurs jours, l'équipe d'assistance de CloudLinux s'est penchée sur le problème. Fondamentalement, les recommandations concernaient les limites d'utilisation établies. Nous avons également vérifié cette question. Avec les limites désactivées (option CageFS pour l'utilisateur) et avec les limites activées en mode PHP en tant que module Apache, le problème n'a pas été observé. Sur cette base, il a été suggéré que CloudLinux influence d'une manière ou d'une autre. En conséquence, à la fin de la semaine, la demande a été transmise au 3ème niveau de support, mais il n'y avait pas encore de solution.



En cours de route, nous avons étudié la documentation Apache sur les modes CGI et LSAPI, mis en place une deuxième instance Apache sur le serveur d'hébergement sur un port différent avec un site de test, éliminé l'influence de Nginx en envoyant des requêtes directement à Apache et en recevant les mêmes codes d'erreur.



La documentation LSAPI a permis de décoller, rien que sur le diagnostic des erreurs 503:

www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki : php: 503-errors

Dans la section Dépannage avancé, il est proposé de tracer les processus trouvés dans le système:



while true; do if mypid=`ps aux | grep $USERNAME | grep lsphp | grep $SCRIPTNAME | grep -v grep | awk '{print $2; }' | tail -1`; then strace -tt -T -f -p $mypid; fi ; done


La commande a été affinée pour enregistrer tous les processus dans des fichiers avec leurs identifiants.



En regardant les fichiers de trace, nous voyons certaines des mêmes lignes:



cat trace.* | tail
...
47307 21:33:04.137893 --- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=42053, si_uid=0} ---
47307 21:33:04.140728 +++ killed by SIGHUP +++
...


Si nous regardons la description de la structure des signaux envoyés par les processus, nous verrons que



pid_t    si_pid;       /* Sending process ID */


Indique l'identifiant du processus qui a envoyé le signal.



Au moment de l'étude des traces, le processus avec le PID 42053 n'est plus dans le système.Par conséquent, en cours de capture des traces, nous avons décidé de surveiller également les processus qui ont envoyé le signal SIGHUP.

Sous le spoiler, des actions sont décrites qui ont permis de déterminer de quel type de processus il s'agit, ainsi que d'obtenir sa trace et des informations supplémentaires sur les processus auxquels il envoie le signal SIGHUP.



Technique de traçage
Console 1.



tail -f /var/www/httpd-logs/sitename.error.log


2.



while true; do if mypid=`ps aux | grep $USERNAME | grep lsphp | grep "sitename" | grep -v grep | awk '{print $2; }' | tail -1`; then strace -tt -T -f -p $mypid -o /tmp/strace/trace.$mypid; fi ; done


3.



while true; do if mypid=`cat /tmp/strace/trace.* | grep si_pid | cut -d '{' -f 2 | cut -d'=' -f 4 | cut -d',' -f 1`; then ps -aux | grep $mypid; fi; done;


4.



seq 1 10000 | xargs -i sh -c "curl -I http://sitename/"


1 , 4 503, 4.



En conséquence, nous avons obtenu le nom du processus, /opt/alt/python37/bin/python3.7 -sbb /usr/sbin/cagefsctl --rebuild-alt-php-ini



qui était exécuté dans le système une fois par minute.



Nous suivons plusieurs processus cagefsctl pour en suivre au moins un du début à la fin:



for i in `seq 1 100`; do strace -p $(ps ax | grep cagefsctl | grep rebuild-alt-php-ini | grep -v grep | awk '{print $1}') -o /tmp/strace/cagefsctl.trace.$(date +%s); done;


Ensuite, nous étudions ce qu'il a fait, par exemple:



cat /tmp/strace/cagefsctl.trace.1593197892 | grep SIGHUP


Des identifiants de processus ont également été obtenus et se sont terminés par un signal SIGHUP. Les processus terminés étaient les processus PHP en cours d'exécution.



Les données reçues ont été transférées au support CloudLinux afin de clarifier la légitimité de ce processus et s'il doit fonctionner avec une telle fréquence.



Plus tard, nous avons reçu une réponse selon laquelle le travail de l'équipe /usr/sbin/cagefsctl --rebuild-alt-php-iniest exécuté correctement, la seule mise en garde est que l'équipe est exécutée trop souvent. Généralement appelé lorsqu'une mise à jour du système ou un changement de paramètres PHP.



Le seul indice qui reste dans ce cas est de vérifier qui est le parent du processus cagefsctl.



Le résultat ne s'est pas fait attendre, et ce qui a été notre surprise - le processus parent de cagefsctl était le processus ispmgrnode. C'était un peu étrange, car le niveau de journalisation du gestionnaire ISP était réglé au maximum et l'appel cagefsctl n'était pas vu dans ispmgr.log.



Maintenant, il y avait suffisamment de données pour contacter également le support ISP System.



Résultat



Le problème a été déclenché après avoir effectué une mise à jour du gestionnaire ISP. En général, la mise à jour de ISP Manager est une situation normale, mais elle a conduit au démarrage du processus de synchronisation qui s'est terminé par une erreur et a été redémarré toutes les minutes. Le processus de synchronisation a appelé le processus cagefsctl, qui à son tour a mis fin aux processus PHP.



La raison du blocage du processus de synchronisation était le travail effectué sur l'hébergement pour moderniser l'équipement. Quelques mois avant l'apparition du problème, un lecteur PCI-e NVMe a été installé sur le serveur, une partition XFS a été créée et montée dans le répertoire / var. Les fichiers des utilisateurs y ont également été transférés, mais les quotas de disque n'ont pas été mis à jour. Les options de montage n'étaient pas suffisantes, il était également nécessaire de changer le type de système de fichiers dans les paramètres du gestionnaire ISP, car il appelle des commandes pour mettre à jour les quotas de disque. Pour Ext4 et XFS, ces commandes sont différentes.



Ainsi, le problème s'est fait sentir plusieurs mois après les travaux.



conclusions



Nous avons nous-mêmes créé le problème, mais ce n'était pas clair jusqu'au dernier moment. Pour l'avenir, nous essaierons de prendre en compte autant de nuances que possible. Avec l'aide de collègues plus formés du support CloudLinux et ISP System, le problème a été résolu. Maintenant, notre hébergement est stable. Et nous avons acquis une expérience qui nous sera utile dans les travaux futurs.



PS: J'espère que la lecture de l'article vous a intéressé et que cela aidera quelqu'un à résoudre rapidement un problème similaire.



All Articles