La aplicación de ejemplo implementa un supervisor básico de fallos para supervisar la fiabilidad del recurso de DNS (in.named). El supervisor de fallos está compuesto por los siguientes elementos:
dns_probe, un programa definido por el usuario que utiliza nslookup para verificar que el recurso de DNS controlado por el servicio de datos de ejemplo se está ejecutando. Si no lo está, este método intenta reiniciarlo localmente o, dependiendo del número de intentos de reinicio, solicita que RGM reubique el servicio de datos en otro nodo.
dns_monitor_start, un método de rellamada que inicia dns_probe. RGM llama automáticamente a dns_monitor_start una vez establecido en línea el servicio de datos de ejemplo si se ha habilitado la supervisión.
dns_monitor_stop, un método de rellamada que detiene dns_probe. RGM llama automáticamente a dns_monitor_stop antes de establecer fuera de línea el servicio de datos de ejemplo.
dns_monitor_check, un método de rellamada que invoca el método Validate para comprobar que el directorio de configuración está disponible cuando el programa PROBE efectúa una recuperación ante fallos del servicio de datos en un nuevo nodo.
El programa dns_probe implementa un proceso en ejecución permanente que comprueba que el recurso de DNS controlado por el servicio de datos de ejemplo esté en ejecución. dns_probe se inicia mediante el método dns_monitor_start, ejecutado automáticamente por RGM una vez establecido en línea el servicio de datos de ejemplo. El método dns_monitor_stop, que se ejecuta antes de que RGM ponga fuera de línea el servicio de datos de ejemplo, detiene este servicio.
Esta sección describe los principales fragmentos del método PROBE para la aplicación de ejemplo, aunque no se describen las funciones comunes a todos los métodos de rellamada como, por ejemplo, la función parse_args(). Esta sección tampoco describe el uso de la función syslog(). Las funciones comunes se describen en Funciones comunes para todos los métodos.
Para conocer la lista completa del método PROBE, consulte Listado de código del programa PROBE .
El análisis se ejecuta en un bucle infinito. Utiliza nslookup para comprobar que se está ejecutando el recurso de DNS correcto. Si no se está ejecutando, el análisis permanece inactivo durante un intervalo preestablecido (mediante la propiedad definida por el sistema Thorough_probe_interval) y realiza de nuevo la comprobación. Si DNS no está en ejecución, este programa intenta reiniciarlo localmente o, dependiendo del número de intentos de reinicio, solicita que RGM reubique el servicio de datos en otro nodo.
Este programa requiere los valores de las siguientes propiedades:
Thorough_probe_interval, para fijar el periodo de reposo del análisis.
Probe_timeout, para forzar el valor de tiempo de espera del análisis en el comando nslookup que realiza el análisis.
Network_resources_used, para obtener la dirección IP en la que se está ejecutando DNS.
Retry_count y Retry_interval, para determinar el número de intentos de reinicio y el periodo durante el que se realiza el recuento de los mismos.
Rt_basedir, para obtener el directorio que contiene el programa PROBE y la utilidad gettime.
La función scha_resource_get() obtiene los valores de estas propiedades y los almacena en variables de shell, como se muestra a continuación:
PROBE_INTERVAL=`scha_resource_get -O Thorough_probe_interval \ -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME` PROBE_TIMEOUT_INFO=`scha_resource_get -O Extension -R $RESOURCE_NAME \ -G $RESOURCEGROUP_NAME Probe_timeout` Probe_timeout=`echo $probe_timeout_info | awk '{print $2}'` DNS_HOST=`scha_resource_get -O Network_resources_used -R $RESOURCE_NAME \ -G $RESOURCEGROUP_NAME` RETRY_COUNT=`scha_resource_get -O Retry_count -R $RESOURCE_NAME -G \ $RESOURCEGROUP_NAME` RETRY_INTERVAL=`scha_resource_get -O Retry_interval -R $RESOURCE_NAME -G \ $RESOURCEGROUP_NAME` RT_BASEDIR=`scha_resource_get -O RT_basedir -R $RESOURCE_NAME -G \ $RESOURCEGROUP_NAME`
Para las propiedades definidas por el sistema, como Thorough_probe_interval , la función scha_resource_get() devuelve sólo el valor. Para las propiedades de extensión, como Probe_timeout, la función scha_resource_get() devuelve el valor y el tipo. Utilice el comando awk para obtener únicamente el valor.
El análisis es en sí mismo un bucle while de los comandos nslookup. Antes del bucle while, se configura un archivo temporal para contener las respuestas de nslookup. Las variables probefail y retries se inicializan en 0.
# Set up a temporary file for the nslookup replies. DNSPROBEFILE=/tmp/.$RESOURCE_NAME.probe probefail=0 retries=0
El bucle while realiza las siguientes tareas:
Establece el intervalo de reposo para el análisis
Utiliza hatimerun para iniciar nslookup, pasa el valor de Probe_timeout e identifica el host de destino.
Establece la variableprobefail en función del éxito o fracaso del código de retorno de nslookup.
Si se establece probefail en 1 (fallo), verifica que la respuesta a nslookup haya provenido del servicio de datos de ejemplo y no de algún otro servidor de DNS.
Éste es el código bucle while.
while : do # The interval at which the probe needs to run is specified in the # property THOROUGH_PROBE_INTERVAL. Therefore, set the probe to sleep # for a duration of THOROUGH_PROBE_INTERVAL. sleep $PROBE_INTERVAL # Run an nslookup command of the IP address on which DNS is serving. hatimerun -t $PROBE_TIMEOUT /usr/sbin/nslookup $DNS_HOST $DNS_HOST \ > $DNSPROBEFILE 2>&1 retcode=$? if [ $retcode -ne 0 ]; then probefail=1 fi # Make sure that the reply to nslookup comes from the HA-DNS # server and not from another nameserver mentioned in the # /etc/resolv.conf file. if [ $probefail -eq 0 ]; then # Get the name of the server that replied to the nslookup query. SERVER=` awk ' $1=="Server:" { print $2 }' \ $DNSPROBEFILE | awk -F. ' { print $1 } ' ` if [ -z "$SERVER" ]; then probefail=1 else if [ $SERVER != $DNS_HOST ]; then probefail=1 fi fi fi
Si la variable probefail tiene un valor diferente a 0 (éxito), se agota el tiempo de espera del comando nslookup o la respuesta proviene de un servidor diferente al servidor de DNS del servicio de ejemplo. En ambos casos, el servidor de DNS no funciona como debería y el supervisor de fallos invoca la función decide_restart_or_failover() para determinar si se debe reiniciar el servicio de datos localmente o solicitar que RGM reubique el servicio de datos en otro nodo. Si la variable probefail es 0, se genera un mensaje en el que se indica que el análisis se ha realizado satisfactoriamente.
if [ $probefail -ne 0 ]; then decide_restart_or_failover else logger -p ${SYSLOG_FACILITY}.err\ -t [$SYSLOG_TAG]\ "${ARGV0} Probe for resource HA-DNS successful" fi
La función decide_restart_or_failover() utiliza un intervalo de tiempo (Retry_interval) y un recuento de fallos (Retry_count) para determinar si se debe reiniciar localmente DNS o solicitar que RGM reubique el servicio de datos en un nodo diferente. Esta función implementa la siguiente lógica condicional. El código se incluye en el listado de decide_restart_or_failover() en Listado de código del programa PROBE .
Si es el primer fallo, se reinicia el servicio de datos. Se registra un mensaje de error y se detiene el contador de la variable retries.
Si no es el primer fallo, pero se ha superado la ventana de tiempo, se reinicia el servicio de datos. Se registra un mensaje de error, se pone a cero el contador y se desliza la ventana.
Si el tiempo se encuentra aún dentro del intervalo y se ha superado el contador de reintentos, se realiza una recuperación ante fallos en otro nodo. Si esta recuperación no se realiza con éxito, se registra un error y el programa de análisis sale con el estado 1 (fallo).
Si el tiempo sigue dentro de la ventana, pero no se ha superado el contador de reintentos, se reinicia el servicio de datos. Se registra un mensaje de error y se restablece el contador en la variable retries.
Si el número de reinicios alcanza el límite durante el intervalo de tiempo, la función solicita que RGM reubique el servicio de datos en otro nodo. Si el número de reinicios está dentro del límite o se ha superado el intervalo, por lo que el recuento vuelve a empezar, la función intenta reiniciar DNS en el mismo nodo. Sobre esta función debe tener en cuenta lo siguiente:
La utilidad gettime se utiliza para realizar un seguimiento del tiempo entre los reinicios. Se trata de un programa C ubicado en el directorio (RT_basedir )..
Las propiedades definidas por el sistema Retry_count y Retry_interval determinan el número de reinicios y el intervalo de tiempo durante el que se realiza un recuento de los mismos. Estas propiedades se configuran de forma predeterminada en 2 intentos de reinicio en un periodo de 5 minutos (300 segundos) en el archivo RTR, aunque el administrador del clúster pueda cambiar estos valores.
La función restart_service() se invoca para reiniciar el servicio de datos en el mismo nodo. Consulte la siguiente sección, Reinicio del servicio de datos, para obtener información sobre esta función.
La función scha_control() de la API, con la opción GIVEOVER, pone fuera de línea el grupo de recursos que contiene el servicio de datos de ejemplo y lo vuelve a establecer en línea en un nodo diferente.
decide_restart_or_failover() llama a la función restart_service() para intentar reiniciar el servicio de datos en el mismo nodo. Esta función ejecuta la siguiente lógica:
Determina si el servicio de datos está aún registrado bajo el control de PMF. Si es así, la función realiza las siguientes acciones:
Obtiene el nombre del método Stop y el valor Stop_timeout para el servicio de datos.
Utiliza hatimerun para iniciar el método Stop para el servicio de datos, pasando el valor de Stop_timeout.
Si el servicio de datos se detiene con éxito, obtiene el nombre del método Start y el valor de Start_timeout para el servicio de datos.
Utiliza hatimerun para iniciar el método Start para el servicio de datos, pasando el valor de Start_timeout.
Si el servicio de datos ya no está registrado con PMF, esto implica que el servicio ha superado el número de máximo de reintentos permitidos bajo el control de PMF. Se llama a la función scha_control() con la opción GIVEOVER para realizar una recuperación ante fallos del servicio de datos en un nodo diferente.
function restart_service { # To restart the data service, first verify that the # data service itself is still registered under PMF. pmfadm -q $PMF_TAG if [[ $? -eq 0 ]]; then # Since the TAG for the data service is still registered under # PMF, first stop the data service and start it back up again. # Obtain the Stop method name and the STOP_TIMEOUT value for # this resource. STOP_TIMEOUT=`scha_resource_get -O STOP_TIMEOUT \ -R $RESOURCE_NAME -G $RESOURCEGROUP_NAMÈ STOP_METHOD=`scha_resource_get -O STOP \ -R $RESOURCE_NAME -G $RESOURCEGROUP_NAMÈ hatimerun -t $STOP_TIMEOUT $RT_BASEDIR/$STOP_METHOD \ -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME \ -T $RESOURCETYPE_NAME if [[ $? -ne 0 ]]; then logger-p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG] \ “${ARGV0} Stop method failed.” return 1 fi # Obtain the START method name and the START_TIMEOUT value for # this resource. START_TIMEOUT=`scha_resource_get -O START_TIMEOUT \ -R $RESOURCE_NAME -G $RESOURCEGROUP_NAMÈ START_METHOD=`scha_resource_get -O START \ -R $RESOURCE_NAME -G $RESOURCEGROUP_NAMÈ hatimerun -t $START_TIMEOUT $RT_BASEDIR/$START_METHOD \ -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME \ -T $RESOURCETYPE_NAME if [[ $? -ne 0 ]]; then logger-p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG] \ “${ARGV0} Start method failed.” return 1 fi else # The absence of the TAG for the dataservice # implies that the data service has already # exceeded the maximum retries allowed under PMF. # Therefore, do not attempt to restart the # data service again, but try to failover # to another node in the cluster. scha_control -O GIVEOVER -G $RESOURCEGROUP_NAME \ -R $RESOURCE_NAME fi return 0 }
El programa PROBE del servicio de datos sale con errores si fallan los intentos de reinicio local y de recuperación ante fallos en un nodo diferente. Este programa registra un mensaje sobre el fallo del intento de recuperación: Failover attempt failed.
RGM invoca el método Monitor_start para iniciar el método dns_probe después de que el servicio de datos de ejemplo se ponga en línea.
En esta sección, se describen las partes más importantes del método Monitor_start de la aplicación de ejemplo, aunque no se describen las funciones comunes a todos los métodos de rellamada como, por ejemplo, la función parse_args(). Esta sección tampoco describe el uso de la función syslog(). Las funciones comunes se describen en Funciones comunes para todos los métodos.
Para obtener un listado completo del método Monitor_start, consulte Listado de código del método Monitor_start .
Este método utiliza PMF (pmfadm) para iniciar el análisis.
El método Monitor_start obtiene el valor de la propiedad RT_basedir para construir el nombre completo de la ruta del programa PROBE. Este método inicia el análisis mediante la opción de pmfadm (-n -1, -t -1), que implica que si el análisis no puede iniciarse, PMF intenta iniciarlo un número infinito de veces durante un periodo ilimitado de tiempo.
# Find where the probe program resides by obtaining the value of the # RT_basedir property of the resource. RT_BASEDIR=`scha_resource_get -O RT_basedir -R $RESOURCE_NAME -G \ $RESOURCEGROUP_NAME` # Start the probe for the data service under PMF. Use the infinite retries # option to start the probe. Pass the resource name, type, and group to the # probe program. pmfadm -c $RESOURCE_NAME.monitor -n -1 -t -1 \ $RT_BASEDIR/dns_probe -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME \ -T $RESOURCETYPE_NAME
RGM llama al método Monitor_stop para detener la ejecución de dns_probe cuando el servicio de datos de ejemplo se pone fuera de línea.
En esta sección, se describen las partes más importantes del método Monitor_start de la aplicación de ejemplo, aunque no se describen las funciones comunes a todos los métodos de rellamada como, por ejemplo, la función parse_args(). Esta sección tampoco describe el uso de la función syslog(). Las funciones comunes se describen en Funciones comunes para todos los métodos.
Para obtener un listado completo del método Monitor_stop, consulte Listado de código del método Monitor_stop.
Este método utiliza PMF (pmfadm) para comprobar si el análisis se está ejecutando y, si es así, detenerlo.
El método Monitor_stop utiliza pmfadm -q para ver si el análisis está en ejecución y, si así fuera, utiliza pmfadm -s para detenerlo. Si el análisis ya está detenido, el método sigue saliendo de forma satisfactoria, lo que garantiza la idempotencia del método.
Asegúrese de utilizar la señal KILL con pmfadm para detener el análisis y no una señal que pueda ocultarse, como TERM. De lo contrario, el método Monitor_stop puede bloquearse indefinidamente y, al final, se puede agotar el tiempo de espera. El motivo es que el método PROBE llama a scha_control() cuando es necesario reiniciar el servicio de datos o realizar una recuperación ante fallos. Cuando scha_control() llama a Monitor_stop como parte del proceso de establecimiento en línea del servicio de datos, si Monitor_stop utiliza una señal que pueda ocultarse, este método Monitor_stop se bloquea mientras espera que se complete scha_control() y scha_control() se bloquea también a la espera de que se complete Monitor_stop.
# See if the monitor is running, and if so, kill it. if pmfadm -q $PMF_TAG; then pmfadm -s $PMF_TAG KILL if [ $? -ne 0 ]; then logger -p ${SYSLOG_FACILITY}.err \ -t [$SYSLOG_TAG] \ "${ARGV0} Could not stop monitor for resource " \ $RESOURCE_NAME exit 1 else # could successfully stop the monitor. Log a message. logger -p ${SYSLOG_FACILITY}.err \ -t [$SYSLOG_TAG] \ "${ARGV0} Monitor for resource " $RESOURCE_NAME \ " successfully stopped" fi fi exit 0
El método Monitor_stop registra un mensaje de error si no puede detener el método PROBE. RGM cambia el estado del servicio de datos a MONITOR_FAILED en el nodo principal, lo que puede provocar una situación de emergencia en el nodo.
Monitor_stop no debería salir antes de que se haya detenido el análisis.
RGM llama al método Monitor_check cuando el método PROBE intenta realizar una recuperación ante fallos del grupo de recursos que contiene el servicio de datos en otro nodo.
En esta sección, se describen las partes más importantes del método Monitor_start de la aplicación de ejemplo, aunque no se describen las funciones comunes a todos los métodos de rellamada como, por ejemplo, la función parse_args(). Esta sección tampoco describe el uso de la función syslog(). Las funciones comunes se describen en Funciones comunes para todos los métodos.
Para obtener un listado completo del método Monitor_check, consulte Listado de código del método Monitor_check .
Debe implementarse el método Monitor_check de tal forma que no entre en conflicto con otros métodos que se estén ejecutando simultáneamente.
El método Monitor_check llama al método Validate para verificar que el directorio de configuración de DNS esté disponible en el nuevo nodo. La propiedad de extensión Confdir señala al directorio de configuración de DNS. Por lo tanto, Monitor_check obtiene el nombre y la ruta del método Validate y el valor de Confdir. Pasa este valor a Validate, como muestra la lista siguiente.
# Obtain the full path for the Validate method from # the RT_basedir property of the resource type. RT_BASEDIR=`scha_resource_get -O RT_basedir -R $RESOURCE_NAME \ -G $RESOURCEGROUP_NAMÈ # Obtain the name of the Validate method for this resource. VALIDATE_METHOD=`scha_resource_get -O Validate \ -R $RESOURCE_NAME -G $RESOURCEGROUP_NAMÈ # Obtain the value of the Confdir property in order to start the # data service. Use the resource name and the resource group entered to # obtain the Confdir value set at the time of adding the resource. config_info=`scha_resource_get -O Extension -R $RESOURCE_NAME \ -G $RESOURCEGROUP_NAME Confdir` # scha_resource_get returns the type as well as the value for extension # properties. Use awk to get only the value of the extension property. CONFIG_DIR=`echo $config_info | awk `{print $2}'` # Call the validate method so that the dataservice can be failed over # successfully to the new node. $RT_BASEDIR/$VALIDATE_METHOD -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME \ -T $RESOURCETYPE_NAME -x Confdir=$CONFIG_DIR
Consulte Funcionamiento del método Validate para comprobar cómo la aplicación de ejemplo comprueba si un nodo es apto para alojar el servicio de datos.