Sun Cluster 数据服务开发者指南(适用于 Solaris OS)

定义故障监视器

应用程序样例实现一个基本的故障监视器,以监视 DNS 资源 (in.named) 的可靠性。故障监视器包括:

探测程序

dns_probe 程序将实现一个持续运行的进程,用来检验数据服务样例所控制的 DNS 资源是否正在运行。dns_probedns_monitor_start 方法启动,使数据服务样例联机后,RGM 将自动调用该方法。该数据服务由 dns_monitor_stop 方法停止,使数据服务样例脱机前,RGM 将调用该方法。

本小节介绍了应用程序样例中的 PROBE 方法的重要方面,但未介绍所有回调方法都通用的功能,例如 parse_args() 函数和获取 syslog 工具,这些在为所有方法提供通用功能中介绍。

要获得 PROBE 方法的完整列表,请参见PROBE 程序

探测程序概述

探测程序以死循环的形式运行。它使用 nslookup 检验适当的 DNS 资源是否正在运行。如果 DNS 正在运行,探测程序将按照指定的时间间隔(由系统定义的特性 Thorough_probe_interval 进行设置)进行休眠,然后再次进行检查。如果 DNS 尚未运行,此程序将尝试在本地重新启动 DNS,或根据尝试重新启动的次数,如果超出此次数则请求 RGM 将数据服务重定位到其他节点。

获取特性值

此程序需要以下特性值:

scha_resource_get() 函数可用来获取这些特性的值,并将其存储在 shell 变量中,如下所示。

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`


注意 –

对于系统定义的特性(例如 Thorough_probe_interval ),scha_resource_get() 仅返回值。对于扩展特性(例如 Probe_timeout),scha_resource_get() 将返回类型和值。使用 awk 命令仅能获取值。


检查服务的可靠性

探测程序本身是 nslookup 命令的 while 死循环。在进行 while 循环之前,将设置一个临时文件,以保留 nslookup 应答。probefailretries 变量初始化为 0。


# Set up a temporary file for the nslookup replies.
DNSPROBEFILE=/tmp/.$RESOURCE_NAME.probe
probefail=0
retries=0

while 循环本身将:

下面是 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

评估重启和故障转移

如果 probefail 变量是 0 (成功)之外的值,这意味着 nslookup 命令超时或表明应答是某个服务器发出的,而不是服务样例的 DNS 发出的。在每种情况下,DNS 服务器都不能发挥预期作用,故障监视器将调用 decide_restart_or_failover() 函数以确定是在本地重新启动数据服务,还是请求 RGM 将数据服务重新定位到其他节点。如果 probefail 变量是 0,则会生成一条表明探测程序成功的消息。


   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

decide_restart_or_failover() 函数使用时间窗口 (Retry_interval) 和故障计数 (Retry_count) 来确定是在本地重新启动 DNS,还是请求 RGM 将数据服务重新定位到其他节点。它实现了以下有条件的代码(请参见PROBE 程序中的 decide_restart_or_failover() 的代码列表)。

如果在指定时间间隔内达到了重新启动的最大次数,函数将请求 RGM 将数据服务重新定位到其他节点。如果重启的次数在所限制范围之内,或者已超出了时间间隔,以致重新开始计数时,该函数将尝试在同一节点上重启 DNS。请注意以下关于此函数的信息:

重启数据服务

decide_restart_or_failover() 调用 restart_service() 函数以试图在同一个节点上重新启动数据服务。该函数执行以下操作。


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
}

探测程序退出状态

如果尝试在本地进行重新启动以及尝试故障转移到其他节点的操作都失败后,数据服务样例的 PROBE 程序将在失败状态下退出。它将记录错误消息“故障转移尝试失败”。

Monitor_start 方法

在使数据服务样例联机之后,RGM 将调用 Monitor_start 方法来启动 dns_probe 方法。

本小节介绍了应用程序样例中的 Monitor_start 方法的重要方面,但未介绍所有回调方法都通用的功能,例如 parse_args() 函数和获取 syslog 工具,这些在为所有方法提供通用功能中介绍。

要获得 Monitor_start 方法的完整列表,请参见Monitor_start 方法

Monitor_start 概述

此方法使用 PMF (pmfadm) 启动探测。

启动探测程序

Monitor_start 方法可用来获取 RT_basedir 特性的值以构造 PROBE 程序的完整路径名。此方法将使用 pmfadm (-n -1, -t -1) 的无限重试选项启动探测程序,这意味着如果该探测程序无法启动,PMF 将在无限长的时间间隔内尝试无限多次地启动该程序。


# 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

Monitor_stop 方法

使数据服务样例脱机后,RGM 将调用 Monitor_stop 方法停止 dns_probe 的执行。

本小节介绍了应用程序样例中的 Monitor_stop 方法的重要方面,但未介绍所有回调方法都通用的功能,例如 parse_args() 函数和获取 syslog 工具,这些在为所有方法提供通用功能中介绍。

要获得 Monitor_stop 方法的完整列表,请参见Monitor_stop 方法

Monitor_stop 概述

此方法将使用 PMF (pmfadm) 查看探测程序是否正在运行,如果正在运行,将停止该程序。

停止监视器

Monitor_stop 方法将使用 pmfadm -q 查看探测程序是否正在运行,如果正在运行,将使用 pmfadm -s 停止该程序。如果探测程序已停止,该方法仍将成功退出,这可以确保该方法的幂等性。


# 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


注意 – 注意 –

请务必通过 pmfadm 使用 KILL 信号停止该探测程序,而不要使用可屏蔽信号,例如 TERM。否则,Monitor_stop 方法将无限期地挂起,最终将会超时。导致此问题的原因是必要时 PROBE 方法会调用 scha_control(),以重启或故障转移数据服务。作为使数据服务脱机进程的一部分,当 scha_control() 调用 Monitor_stop 时,如果 Monitor_stop 使用可屏蔽信号,它将挂起,等待 scha_control() 的完成,且 scha_control() 也将挂起,等待 Monitor_stop 的完成。


Monitor_stop 退出状态

如果 Monitor_stop 方法无法停止 PROBE 方法,它将记录一条错误消息。RGM 将使数据服务样例在主节点上处于 MONITOR_FAILED 状态,此操作可能会影响该主节点。

在探测程序停止之前,Monitor_stop 不应退出。

Monitor_check 方法

每当 PROBE 方法视图将包含数据服务的资源组故障转移到新节点上时,RGM 都将调用 Monitor_check 方法。

本小节介绍了应用程序样例中的 Monitor_check 方法的重要方面,但未介绍所有回调方法都通用的功能,例如 parse_args() 函数和获取 syslog 工具,这些在为所有方法提供通用功能中介绍。

要获得 Monitor_check 方法的完整列表,请参见Monitor_check 方法

必须实现 Monitor_check 方法,以免与同时运行的其他方法发生冲突。

Monitor_check 方法将调用 Validate 方法来检验 DNS 配置目录在新节点上是否可用。Confdir 扩展特性指向 DNS 配置目录。因此,Monitor_check 将获取 Validate 方法的路径和名称以及 Confdir 的值。它将把此值传送到 Validate,如下所示。


# 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

要了解应用程序样例如何检验一个节点是否适合用作数据服务主机,请参见Validate 方法