Dic 292012
 
Artículo Administración de Servidores

(Read this post in english)
Un servidor típico en internet, ya sea un blog de WordPress, o un sitio que utiliza un gestor de contenidos Joomla, Drupal u otro tipo de CMS, requiere al menos dos servicios que deben estar permanentemente en ejecución: un servidor web apache, y un servidor de base de datos mysql.

Pero incluso en el servidor más estable, puede ocurrir que uno de estos servicios se encuentre con algún problema inesperado que provoque su finalización.

Por esta razón, es muy conveniente disponer de un script “monitor de servicios” que compruebe periódicamente el estado de los servicios críticos, y reaccione cuando uno de ellos no está activo, generando una alerta e intentando volver a arrancarlo.

En este artículo presentamos un sencillo ejemplo de script de monitorización de apache y mysql sobre un servidor linux, que puede extenderse fácilmente a la monitorización de otros servicios críticos.

 Identificadores de proceso

En linux, cada proceso tiene un identificador numérico (process ID, PID), que se le asigna en el momento en que comienza su ejecución. En linux hay numerosas utilidades que nos permiten interactuar con un proceso, dandole el identificador de proceso como argumento.

Para obtener el PID de un proceso, podemos utilizar comandos tales como “ps” (process status) o “top”. Por ejemplo, para obtener el PID de los procesos apache se se están ejecutando en un servidor Debian:

$ ps -fC apache2
UID        PID  PPID  C STIME TTY          TIME CMD
root      8065     1  0 03:33 ?        00:00:01 /usr/sbin/apache2 -k start
www-data  8099  8065  0 03:33 ?        00:00:00 /usr/sbin/apache2 -k start
www-data  8101  8065  0 03:33 ?        00:00:00 /usr/sbin/apache2 -k start
www-data  8106  8065  0 03:33 ?        00:00:27 /usr/sbin/apache2 -k start
www-data  8107  8065  0 03:33 ?        00:00:26 /usr/sbin/apache2 -k start

En el ejemplo, vemos cinco procesos en ejecución. El proceso con UID root y PID 8065 es el proceso padre. En los otros cuatro subprocesos, el valor en la columna PPID (parent process ID, identificador del proceso padre)  es también 8065, indicando que se trata de subprocesos del mismo.

Fichero PID de apache

Por otra parte, en el fichero de configuración “/etc/apache2/envvars” del servidor web apache, podemos especificar el nombre de un fichero en que se escribe el PID del proceso padre cuando comienza a ejecutarse. En una instalación típica, este fichero se llama “/var/run/apache2.pid”:

$ cat /var/run/apache2.pid
8065

Fichero PID de MySQL

Igual que apache, MySQL también escribe en un fichero el identificador de proceso. El nombre de este fichero se puede especificar con el argumento “–pid-file”, y se puede obtener como parte de la salida generada por el comando “sudo mysqld –print-defaults”:

$ sudo mysqld --print-defaults
mysqld would have been started with the following arguments:
--user=mysql --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/run/mysqld/mysqld.sock --port=3306 
--basedir=/usr --datadir=/var/lib/mysql --tmpdir=/tmp --language=/usr/share/mysql/english 
--skip-external-locking --innodb_file_per_table --bind-address=127.0.0.1 --key_buffer=16M 
--max_allowed_packet=16M --thread_stack=192K --thread_cache_size=8 --myisam-recover=BACKUP 
--query_cache_limit=1M --query_cache_size=16M --general_log_file=/var/log/mysql/mysql.log --general_log=0 
--expire_logs_days=10 --max_binlog_size=100M

Como podemos ver en el ejemplo, el nombre del fichero PID de MySQL en este caso  es “/var/run/mysqld/mysqld.pid”.

Determinar si un proceso está en ejecución

Conociendo el PID de un proceso, podemos utilizar comandos como ps, lsof, strace, etc que proporcionan mucha información sobre el mismo.

En nuestro caso, queremos determinar si los servicios apache y mysql están activos, para lo cual basta con comprobar que el proceso padre de cada uno de ellos está en ejecución. Esto lo podemos hacer pasando el PID del proceso al comando “ps”. “ps” devolverá un código de status distinto de cero si el PID que se le indica no corresponde a un proceso en ejecución.

Si determinamos que el proceso no está en ejecución, procedemos a realizar las acciones que correspondan: Enviar un email de alerta, reiniciar el servicio,…

En el siguiente script de ejemplo “monitor_servicios.sh”, imprimimos un mensaje de error e intentamos reiniciar el servicio:

#!/bin/sh

    pidfile="/var/run/apache2.pid"

    if [ -e $pidfile ];
    then
        OLDPID=`sudo cat $pidfile` > /dev/null;
        ps $OLDPID > /dev/null || {
            echo "ERROR: el servidor web apache no está ejecutándose. Iniciando apache...";

            sudo rm -f $pidfile || {
                echo "ERROR: no se puede borrar el fichero PID de apache ($pidfile), abandonando";
                exit 1;
            }
            sudo /etc/init.d/apache2 start
        }
    else
        echo "El fichero PID $pidfile no existe. Iniciando apache..."
        sudo /etc/init.d/apache2 start
    fi

El script se puede extender fácilmente para que compruebe también el estado del proceso mysql, especificando el fichero PID y el comando de arranque correspondientes:

    pidfile="/var/run/mysqld/mysqld.pid"

    if [ -e $pidfile ];
    then
        OLDPID=`sudo cat $pidfile` > /dev/null;
        ps $OLDPID > /dev/null || {
            echo "ERROR: mysqld no está ejecutándose. Iniciando MySQL...";

            sudo rm -f $pidfile || {
                echo "ERROR: no se puede borrar el fichero pid de mysql ($pidfile), abandonando";
                exit 1;
            }
            sudo /etc/init.d/mysql start
        }
    else
        echo "El fichero PID $pidfile no existe. Iniciando MySQL..."
        sudo /etc/init.d/mysql start
    fi

Automatizando la monitorización de los servicios

Una vez que hemos preparado el script para que monitorice los servicios, podemos automatizar su ejecución cada cinco minutos, añadiendo al crontab una entrada de la forma:

3,8,13,18,23,28,33,38,43,48,53,58 * * * * /path_to_script/monitor_servicios.sh 2>&1

Si el script detecta que un servicio no está en ejecución, imprime un mensaje, y el servidor cron se encargará de enviarlo por email al usuario en el que se ha configurado la entrada.


Indice de artículos sobre administración y uso de MySQL

 Publicado por en 10:49 pm

 Deja un comentario

(requerido)

(requerido)