Apache checker: un script comprobador de Apache en bash

apache-checker-logo

La gestión de servidores es un tema apasionante, pero exige mucho control sobre los sistemas a administrar. Personalmente en la empresa de hospedaje que administro llamada Quijost necesitamos un riguroso control de los servicios para detectar cualquier mal funcionamiento o sobrecarga y obtener una solución de forma casi inmediata.

Uno de los principales problemas es la gestión de recursos de memoria en servidores con Apache y que por lo general suelen usar Cpanel.

Cpanel es un buen sistema de panel de administración, pero es muy exigente en recursos y a veces consume demasiada memoria llegando a colapsar sus propios procesos e invocando a daemons encargados de reiniciarlo.

El problema viene cuando Cpanel además provoca un mal funcionamiento de Apache o bien tenemos un exceso de consumo en servidor por algún efecto Barrapunto, Menéame, Digg, etc.

En esos casos Apache atenderá todas las peticiones posibles dada la memoria de la que dispongamos. Normalmente y como referencia unas 200 peticiones por segundo con 1 GB de RAM (aunque tened presente que esta cifra puede variar bastante según configuraciones y hardware).

Cuando el servidor se quede sin memoria, las peticiones no se atenderán incluso otros servicios como emails (exim) pueden colapsar. Para evitar estas situaciones, he desarrollado un script que se encarga de comprobar periodicamente mediante una tarea cron, los recursos del sistema, la disponibilidad de Apache y la memoria disponible en el servidor, para actuar en consecuencia y reiniciar si es necesario, además de notificar a los administradores y mantener un log.

El script llamado Apache Checker está escrito en bash y tiene el siguiente aspecto:

# Apache Checker: a script for check resources on apache servers
# Author: Shakaran (http://www.shakaran.net)
# License: GPLv3

# For CentOs servers require bc and mutt:
# yum install bc
# yum install mutt

# Uses:
# Add this script to a cron's task with crontab -e
# For example: For run the checking every minute
# */1 * * * * /apache_check.sh &> /dev/null 

# Exit immediately if a simple command exits with a non-zero status
set -e

# Number of current apache2 processes.
N_CURRENT="$(ps aux | grep apache2 | wc -l)"
N_MIN="1"
DESTINY_EMAIL="your-server-admin-address@domain.com"
USER=`id -un` # For example: root
HOST=`hostname`
USERHOST=$USER@$HOST

THRESHOLD=90 # Max threshold for restart apache
TOTAL_MEMORY=$(free | grep "Mem:" | awk '{print $2}')
REMAINING_MEMORY=$(free | grep "Mem:" | awk '{print $4}')
CURRENT_MEMORY=$(echo "($REMAINING_MEMORY/$TOTAL_MEMORY)*100.0" | bc -l)

MAX_NPROCESS_APACHE=5
NPROCESS_APACHE=`ps fu $USERNAME  | awk '/processname/ { x++ } END{print x}'`

if [ "$N_CURRENT" -lt "$N_MIN" ]; then
    apachectl restart
    echo "$HOST: The Apache process is not working and it has been restarted."
    echo "$HOST: The Apache process is not working and it has been restarted." \
    >> /var/log/apache_restarter.log
    SUBJECT="Script Apache checker: start"
    echo "$HOST: The Apache process is not working and it has been restarted." | mutt -s "$SUBJECT" $DESTINY_EMAIL
fi 

ps -fea | grep "/usr/sbin/apache2"
if test ! $? -eq 0 then
    apachectl start
    echo "$HOST: Apache has stopped and it has been reactivated."
    echo "$HOST: Apache has stopped and it has been reactivated." \
    >> /var/log/apache_restarter.log
    SUBJECT="Script Apache checker: restart"
    echo "$HOST: Apache has stopped and it has been reactivated." | mutt $DESTINY_EMAIL
-s "$SUBJECT"
fi

if [ $CURRENT_MEMORY -gt $THRESHOLD ]; then
    apachectl restart
    echo "$HOST: Restarted apache on `date +'%Y-%m-%d %H:%M:%S'`. RAM utilization at
${CURRENT_MEMORY}%"
    echo "$HOST: Restarted apache on `date +'%Y-%m-%d %H:%M:%S'`. RAM utilization at
${CURRENT_MEMORY}%" \
    >> /var/log/apache_restarter.log
    echo "Restarted apache on `date +'%Y-%m-%d %H:%M:%S'`. RAM utilization at
${CURRENT_MEMORY}%" \
    >> /var/log/apache_restarter.log
    SUBJECT="Script Apache checker: restart"
    echo "$HOST: Restarted apache on `date +'%Y-%m-%d %H:%M:%S'`. RAM utilization at
${CURRENT_MEMORY}%" | mutt $DESTINY_EMAIL -s "$SUBJECT"
fi

if [ `ps fu $USERNAME  | awk '/processname/ { x++ } END{print x}'`>
$MAX_NPROCESS_APACHE] then
    echo "$HOST: max number of apache process = ${MAX_NPROCESS_APACHE} `date
+'%Y-%m-%d %H:%M:%S'`. RAM utilization at ${CURRENT_MEMORY}% "
    echo "$HOST: max number of apache process = ${MAX_NPROCESS_APACHE} `date
+'%Y-%m-%d %H:%M:%S'`. RAM utilization at ${CURRENT_MEMORY}% " \
    >> /var/log/apache_restarter.log
    SUBJECT="Script Apache checker: max number of apache process"
    echo "$HOST: max number of apache process = ${MAX_NPROCESS_APACHE} `date
+'%Y-%m-%d %H:%M:%S'`. RAM utilization at ${CURRENT_MEMORY}% " | mutt $DESTINY_EMAIL
-s "$SUBJECT"
fi

El script esta basado en bash y ha sido probado en servidores GNU/Linux CentOs 5.4, pero debería funcionar en cualquier distribución que soporte bash. Como únicos requisitos necesita tener instalados los programas mutt (para enviar correo) y bc (para calcular datos). En CentOs puedes instalarlos con:

# yum install bc mutt

Además para su instalación necesitas añadir una tarea cron que ejecute el script periodicamente, por ejemplo para cada minuto, abre tu editor de cron con:

# crontab -e

Y suponiendo que pones el script en / escribe:

*/1 * * * * /apache_check.sh &> /dev/null

Nota: se asume que el usuario que ejecuta el script tiene permisos de ejecución para Apache y programas bc y mutt que se utilizan (normalmente root), de lo contrario no funcionará correctamente.

¿como funciona?

El script necesita que configures una dirección de envío para los mails de notificación, que puedes cambiar en el valor de la variable DESTINY_EMAIL.

La primera comprobación que hace el script es para evitar ataques DDOS en los que se intentan que Apache haga muchos procesos hijos y sature el servidor (esto puede ser limitado en Apache) pero por si hubiese alguna manera de que el atacante lo incrementara o superase, el script reiniciará apache en caso de que haya muchos procesos y de esta manera se pueda liberar memoria. Para establecer el numero minimo y máximo, se pueden configurar las variables N_MIN y MAX_NPROCESS_APACHE respectivamente.

La segunda comprobación consiste en comprobar si apache esta funcionando, por si hubiese colapsado podamos volverlo a su ejecución normal.

La tercera comprobación establece un límite de consumo de memoria en el servidor, para que en tal caso (suponiendo que es Apache en que la consume) se reinicie apache y se liberen recursos. Por defecto este limite es el 90% de memoria del servidor y puede ser cambiado con la variable THRESHOLD.

De esta manera se puede conseguir tener un servidor un poco más optimizado al uso de memoria y tener constancia de cuando se producen picos debidos a Apache.

El script lo libero con licencia GPLv3 para todos aquellos que lo necesiten y quieran hacer uso de él.

Puedes descargarlo comprimido aquí: [download id="27"]

Todas la mejoras, sugerencias, fallos y críticas son bien recibidas.

8 pensamientos sobre “Apache checker: un script comprobador de Apache en bash”

  1. Discrepo mucho de algunas expresiones. Cpanel no consume mucho, Cpanel no causa que Apache tenga un mal funcionamiento por exceso de visitas.

    Cpanel/WHM como todo, no es la panacea, y lo que ocurre es que hay mucho Sysadmin de Revista Semanal.

    Muy bueno el aporte, pero si quieres un mejor que puede tunear y mas completo es el de R-FXN, SIM Monitor,… completisimo y si lo tuneas JAMAS tendras que hacer nada por salvar una maquina que se pira… lo hara el http://www.rfxn.com/projects/system-integrity-monitor/

    Un saludo.

  2. Hola Abkrim,

    Cada cual tiene sus impresiones, todas respetables. Por mi parte, con casi 600 clientes, en varios VPS y dedicados, tengo bastantes datos para asegurar que consume bastante RAM, con instalación base, modificaciones y diferentes configuraciones. Te hablo solo de lo que es el binario cpanel y utilidades de bandwidth, backup, etc que utiliza, ya solo de base consume entre 450-600 mb. Con cargas incluso puede llegar a 1 o 2 GB, sobre todo si se usa su editor de código. Pero como todo, cada cual tendra su impresion y conclusiones, no es cuestión de convencer a nadie.

    Por mi parte, aunque sigo usando Cpanel, colaboro/desarrollo en otros proyectos como Kloxo e HyperVM de LxCenter como panel open source y gratuito alternativo, que por ejemplo ofrece funcionalidades muy similares con apenas 30 MB de consumo base.

    Respecto a SIM, no lo conocía y parece bastante interesante, lo probare en algunas máquinas de pruebas que no tengo en producción durante algunas semanas ;) Gracias por tu sugerencia.

  3. En un VPS de 512 MB no recomiendo tener muchos procesos de Apache (cada uno es un hilo que consumirá un mínimo de por si). Con MAX_NPROCESS_APACHE se limita a un número pequeño, aunque eso debes de configurarlo de por si en el httpd.conf de Apache también.

    Para un VPS de 512 MB, no re recomendaría poner Apache, mejor lighthttpd o nginx que consumen bastante menos. Incluso mejor que BIND, pondría djbdns que puede ahorrarte unos 50 MB de ram y utilizando las mismas funcionalidades.

    Todas esas características se ofrecen en los VPS de http://quijost.com/vps/ y se puede eligir instalar Kloxo, teniendo un consumo mínimo y permitiendo tener muchas peticiones en tu VPS.

    Saludos

  4. Gracias por tu respuesta, el problema de no usar apache, es perder el manejo de permisos de php, para los gestores de contenido, que con apache se soluciona con suPHP u/o otras bibliotecas. nosé si light soluciono este inconveniente.

    lo otro estoy intentando usar tu bash pero si ejecuto en una terminal
    ps aux | grep apache2 | wc -l

    me marca uno, lo cual es correcto..

    pero si imprimo la variable $N_CURRENT esta vale 0

    por lo que siempre se reinicia apache. ¿Tienes alguna idea de que puede ser,?

    gracias

  5. ps aux | grep apache

    Te devolvera los procesos activos de apache, pero en realidad, filtra por todos los procesos que tengan “apache”. Puesto que tambien se ejecuta “grep apache”, el grep en si tiene la cadena apache, luego, este es el uno que te sale.

  6. hola necesito ayuda con un foro vbulletin me pone loco el consumo de apache en mi servidor con estas característicasNúmero de núcleos de CPU AMD Opteron™ 1385
    Memoria ram8 GB
    Disco duro 160 GB Intel X-25M SSD
    Frecuencia de intervalo 4 x 2.7 GHz
    Trafico incluido 3.000 GB

    Tenemos dos pequeñas webs y un foro vbulletin pero cuando el foro pasa
    de 150 / 200 personas en linea el apache se pone al rojo vivo supongo no
    esta configurado correctamente la verdad ya no sabemos que hacer buscamos
    algún experto que pueda ayudarnos claro esta pagando,ademas siempre
    estamos haciendo cositas nuevas de encontrar a alguien serioque aveces en
    este mundo no abunda y ya nos an engallado se le daría toda esa faena a el
    Manuel valencia dafonte contacto@catalunyafutbol.cat por favor buscamos yuda por supuesto pagaremos el servicio y daremos mas faena

  7. Hola, está muy bueno la información, pero tengo una pregunta, descargue el script y cuando lo ejecuto me sale esto

    ./apache_checker.sh: line 51: syntax error near unexpected token `fi’

    No he podido determinar que está pasando. sabes porq qué?

    Muchas gracias

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *

Puedes usar las siguientes etiquetas y atributos HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>