Error HTTP 503. Servicio no disponible: un caso de soporte de alojamiento

El trabajo en el soporte de alojamiento es básicamente del mismo tipo, la mayoría de las solicitudes de los clientes se resuelven de acuerdo con un esquema bien desarrollado, pero a veces todavía tiene que enfrentar problemas no triviales. Entonces, la tarea principal del ingeniero es encontrar el uno, el único camino correcto que conducirá a su solución. En este artículo quiero hablar sobre cómo encontramos el error flotante "Error HTTP 503. Servicio no disponible" en nuestro alojamiento compartido, cómo tratamos de detectarlo, lo diagnosticamos y obtuvimos un final inesperado.



comienzo



El alojamiento proporciona a los usuarios una pila típica de Linux + Apache + Mysql + PHP y un contenedor de administración. En nuestro caso, este es el negocio de ISP Manager 5 basado en Centos 7 con conversión a CloudLinux. Desde el punto de vista administrativo, CloudLinux proporciona herramientas para administrar límites, así como un selector PHP con varios modos de operación (CGI, FastCGI, LSAPI).



Esta vez un cliente nos contactó con el siguiente problema. Su sitio en el motor de Wordpress periódicamente comenzó a dar 503 errores, de los cuales nos informó.



Los códigos de respuesta que comienzan con 50x se refieren a problemas del lado del servidor. Estos pueden ser problemas tanto del sitio en sí como del servidor web que los atiende.



Situaciones típicas en las que recibimos los siguientes errores:



  • 500 Error interno del servidor: a menudo se asocia con errores de sintaxis en el código del sitio o con bibliotecas faltantes / versión PHP no compatible. También puede haber problemas para conectarse a la base de datos del sitio o permisos incorrectos en archivos / directorios
  • 502 Bad Gateway: por ejemplo, si Nginx se refiere al puerto del servidor web Apache incorrecto, o el proceso Apache deja de funcionar por alguna razón
  • 504 Gateway Timeout: la respuesta de Apache no se recibió dentro del tiempo especificado en la configuración del servidor web
  • 508 Se alcanza el límite de recursos: se ha excedido el límite de recursos asignados al usuario


Esta lista contiene solo algunos de los casos más comunes. También vale la pena señalar que cuando se exceden los límites, el usuario puede recibir errores 500 y 503.



Al diagnosticar estos errores, el primer paso es verificar los registros del servidor web. Esto suele ser suficiente para identificar al culpable y solucionar el problema.



Con respecto al error 503 en nuestro caso, vimos una entrada en los registros:

[lsapi: error] [pid 49817] [cliente xxxx: 6801] [host XXX.XX] Error al enviar la solicitud (GET /index.php HTTP / 1.0); uri (/index.php) content-length (0): ReceiveAckHdr: nada que leer del backend (LVE ID 8514), consulte docs.cloudlinux.com/mod_lsapi_troubleshooting.html
Basado solo en este registro, no fue posible determinar cuál podría ser el problema.



Diagnóstico primario



Inicialmente, verificamos las estadísticas de usuarios que exceden los límites. Se registraron excesos menores en los días anteriores, pero los errores en los registros eran recientes, además, aparecían en el registro a intervalos de uno a varios minutos.



También estudiamos las recomendaciones de CloudLinux usando el enlace provisto en los registros de errores.

Cambiar cualquier parámetro no trajo ningún resultado.



El sitio utilizó una base de datos en un servidor Mysql 5.7 que se ejecuta en el mismo servidor en un contenedor Docker. Los registros del contenedor contenían mensajes:



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


Solo entre estos mensajes había mensajes sobre la conexión interrumpida del sitio bajo investigación. Esto dio por supuesto que la conexión al DBMS no se realiza correctamente. Para verificarlo, implementamos una copia del sitio en un dominio de prueba, convertimos la base de datos del sitio a la versión nativa de Centos 7 del DBMS 5.5.65-MariaDB. En el sitio de prueba, se ejecutaron varios cientos de solicitudes utilizando la utilidad curl. El error no pudo ser reproducido. Pero este resultado fue preliminar y después de la conversión de la base de datos en el sitio de producción, el problema persistió.



Por lo tanto, se eliminó el problema de la conexión incorrecta al DBMS.



La siguiente sugerencia fue verificar si había algún problema con el sitio en sí. Para hacer esto, configuramos un servidor virtual separado, en él creamos el entorno más similar. La única diferencia significativa es la falta de CloudLinux. El problema no se pudo reproducir en el servidor de prueba. Por lo tanto, hemos determinado que todo está en orden en el código del sitio. Sin embargo, tratamos de deshabilitar los complementos de Wordpress de la misma manera, pero el problema persistió.



Como resultado, llegamos a la conclusión de que el problema está en nuestro alojamiento.



Después de analizar los registros de otros sitios, se descubrió que el problema se observa en muchos de ellos. Unas 100 piezas en el momento de la verificación:



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


Durante las pruebas, descubrimos que un CMS Wordpress limpio y recién instalado también genera periódicamente el error 503.



Aproximadamente 2 meses antes de eso, realizamos trabajos para modernizar el servidor, en particular, cambiamos el modo de operación de Apache de Worker a Prefork, para poder usar PHP en LSAPI en lugar de CGI lento. Se suponía que esto podría afectar, o se requieren algunas configuraciones adicionales de Apache, pero no pudimos volver al modo Trabajador. Durante el cambio del modo operativo Apache, se cambian todas las configuraciones del sitio, el proceso no es rápido y no todo podría funcionar sin problemas.



La corrección de la configuración de Apache tampoco dio el resultado deseado.



En el camino, buscamos problemas similares en los motores de búsqueda. En uno de los foros, los participantes argumentaron que el proveedor de alojamiento tiene un problema y debe cambiarse si el problema no se resuelve. No suena muy optimista cuando estás del otro lado, pero puedes entender al cliente. ¿Por qué necesita un hosting que no funcione?



En esta etapa, hemos recopilado la información disponible y los resultados del trabajo realizado. Fueron contactados para apoyar CloudLinux.



Diagnósticos detallados



Durante varios días, el personal de soporte de CloudLinux profundizó en el problema. Básicamente, las recomendaciones se referían a los límites de usuario establecidos. También verificamos esta pregunta. Con los límites deshabilitados (opción CageFS para el usuario) y con los límites habilitados en modo PHP como módulo Apache, no se observó el problema. En base a esto, se ha sugerido que CloudLinux está influyendo de alguna manera. Como resultado, al final de la semana, la solicitud se escaló al tercer nivel de soporte, pero aún no había solución.



En el camino, estudiamos la documentación de Apache en los modos CGI y LSAPI, configuramos una segunda instancia de Apache en el servidor de alojamiento en un puerto diferente con un sitio de prueba, eliminamos la influencia de Nginx enviando solicitudes directamente a Apache y obteniendo los mismos códigos de error.



La documentación de LSAPI ayudó a despegar, solo sobre el diagnóstico de errores 503:

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

En la sección Solución avanzada de problemas, se propone rastrear los procesos encontrados en el sistema:



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


El comando se ha refinado para registrar todos los procesos en archivos con sus identificadores.



Al mirar los archivos de rastreo, vemos algunas de las mismas líneas:



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 observamos la descripción de la estructura de las señales enviadas por los procesos, veremos que



pid_t    si_pid;       /* Sending process ID */


Indica el identificador del proceso que envió la señal.



Al momento de estudiar las trazas, el proceso con PID 42053 ya no se encuentra en el sistema, por lo tanto, en el proceso de captura de trazas, decidimos monitorear los procesos que también enviaron la señal SIGHUP.

Bajo el spoiler, se describen acciones que hicieron posible determinar qué tipo de proceso es, así como obtener su rastreo e información adicional sobre a qué procesos envía la señal SIGHUP.



Técnica de seguimiento
Consola 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.



Como resultado, obtuvimos el nombre del proceso /opt/alt/python37/bin/python3.7 -sbb /usr/sbin/cagefsctl --rebuild-alt-php-ini



, que se llevó a cabo en el sistema una vez por minuto.



Trazamos varios procesos cagefsctl para rastrear al menos uno de principio a 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;


A continuación, estudiamos lo que hizo, por ejemplo:



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


También se obtuvieron ID de proceso que terminaron con una señal SIGHUP. Los procesos terminados fueron los procesos PHP actualmente en ejecución.



Los datos recibidos se transfirieron al soporte de CloudLinux para aclarar la legitimidad de este proceso y si debería funcionar con tanta frecuencia.



Más tarde, recibimos una respuesta de que el trabajo del equipo /usr/sbin/cagefsctl --rebuild-alt-php-inise está realizando correctamente, la única advertencia es que el equipo se ejecuta con demasiada frecuencia. Generalmente se llama cuando cambia una actualización del sistema o la configuración de PHP.



La única pista que queda en este caso es verificar quién es el padre de cagefsctl.



El resultado no tardó en llegar, y cuál fue nuestra sorpresa: el proceso principal para cagefsctl fue el proceso ispmgrnode. Fue un poco extraño, porque el nivel de registro para el Administrador de ISP se estableció al máximo y la llamada cagefsctl no se vio en ispmgr.log.



Ahora también había suficientes datos para contactar al soporte del sistema ISP.



Salir



El problema se desencadenó después de realizar una actualización de ISP Manager. En general, la actualización del Administrador de ISP es una situación normal, pero condujo al inicio del proceso de sincronización, que terminó con un error y se reinició cada minuto. El proceso de sincronización invocó el proceso cagefsctl, que a su vez terminó los procesos PHP.



El motivo del bloqueo del proceso de sincronización fue el trabajo realizado en el alojamiento para modernizar el equipo. Unos meses antes de que ocurriera el problema, se instaló una unidad PCI-e NVMe en el servidor, se creó una partición XFS y se montó en el directorio / var. Los archivos de los usuarios también se transfirieron a él, pero las cuotas de disco no se actualizaron. Las opciones de montaje no eran suficientes, también era necesario cambiar el tipo de sistema de archivos en los parámetros del Administrador de ISP, ya que invoca comandos para actualizar las cuotas de disco. Para Ext4 y XFS, estos comandos son diferentes.



Así, el problema se hizo sentir varios meses después del trabajo.



conclusiones



Nosotros mismos creamos el problema, pero no quedó claro hasta el último momento. Para el futuro, intentaremos tener en cuenta tantos matices como sea posible. Con la ayuda de colegas más capacitados de CloudLinux y el soporte del sistema ISP, el problema se resolvió. Ahora nuestro hosting es estable. Y hemos adquirido experiencia que nos será útil en futuros trabajos.



PD: Espero que estés interesado en leer el artículo, y ayudará a alguien a resolver rápidamente un problema similar.



All Articles