サンプルのアプリケーションは、DNS リソース (in.named) の信頼性を監視する基本的な障害モニターを実装します。
障害モニターは、次の要素から構成されます。
dns_probe - nslookup を使用し、サンプルのデータサービスの制御下にある DNS リソースが動作しているかどうかを確認するユーザー定義プログラム。DNS が動作していない場合、このメソッドは DNS をローカルで再起動しようとします。あるいは、再起動の再試行回数によっては、RGM がデータサービスを別のノードに再配置することを要求します。
dns_monitor_start - dns_probe を起動するコールバックメソッド。監視が有効である場合、RGM は、サンプルのデータサービスがオンラインになったあと、自動的に dns_monitor_start を呼び出します。
dns_monitor_stop - dns_probe を停止するコールバックメソッド。RGM は、サンプルのデータサービスがオフラインになる前に、自動的に dns_monitor_stop を呼び出します。
dns_monitor_check - PROBE プログラムがデータサービスを新しいノードにフェイルオーバーするとき、Validate メソッドを呼び出し、構成ディレクトリが利用可能であるかどうかを確認するコールバックメソッド。
dns_probe プログラムは、サンプルのデータサービスの管理下にある DNS リソースが動作しているかどうかを確認する、連続して動作するプロセスを実行します。dns_probe は、サンプルのデータサービスがオンラインになったあと、RGM によって自動的に実行される dns_monitor_start メソッドによって起動されます。データサービスは、サンプルのデータサービスがオフラインになる前、RGM によって実行される dns_monitor_stop メソッドによって停止されます。
この節では、サンプルのアプリケーションの PROBE メソッドの重要な部分だけを説明します。parse_args() 関数など、すべてのコールバックメソッドに共通な機能については説明しません。また、syslog() 関数の使用法についても説明しません。共通の機能については、「すべてのメソッドに共通な機能の提供」を参照してください。
PROBE メソッドの完全なリストについては、「PROBE プログラムのコードリスト」を参照してください。
検証プログラムは無限ループで動作します。検証プログラムは、nslookup を使用し、適切な DNS リソースが動作しているかどうかを確認します。DNS が動作している場合、検証プログラムは一定の期間 (Thorough_probe_interval システム定義プロパティーに設定されている期間) だけ休眠し、再び検証を行います。DNS が動作していない場合、検証プログラムは DNS をローカルで再起動しようとするか、再起動の再試行回数によっては、RGM がデータサービスを別のノードに再配置することを要求します。
このプログラムには、次のプロパティーの値が必要です。
Thorough_probe_interval – 検証プログラムが休眠する期間を設定します。
Probe_timeout – nslookup コマンドが検証を行う期間 (タイムアウト値) を設定します。
Network_resources_used – DNS が動作するサーバーを設定します。
Retry_count と Retry_interval – 再起動を行う回数と期間を設定します。
RT_basedir – PROBE プログラムと gettime ユーティリティーが格納されているディレクトリを設定します。
scha_resource_get() 関数は、次に示すように、上記プロパティーの値を取得し、シェル変数に格納します。
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 の応答を保管する一時ファイルを設定します。probefail 変数と retries 変数は 0 に初期化されます。
# Set up a temporary file for the nslookup replies. DNSPROBEFILE=/tmp/.$RESOURCE_NAME.probe probefail=0 retries=0
while ループは、次の作業を行います。
検証プログラム用の休眠期間を設定します。
hatimerun を使用して nslookup を起動し、Probe_timeout の値を渡し、ターゲットホストを指定します。
nslookup の戻りコード (成功または失敗) に基づいて、probefail 変数を設定します。
probefail が 1 (失敗) に設定された場合、nslookup への応答がサンプルのデータサービスから来ており、ほかの DNS サーバーから来ているのではないことを確認します。
次に、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() を参照してください。
最初の障害である場合、データサービスをローカルで再起動します。エラーメッセージを記録し、retries 変数の再試行カウンタをインクリメントします。
最初の障害ではなく、再試行時間が再試行最大期間を過ぎている場合、データサービスをローカルで再起動します。エラーメッセージを記録し、再試行カウンタをリセットし、再試行時間をリセットします。
再試行時間が再試行最大期間を過ぎておらず、再試行カウンタが再試行最大回数を超えている場合、別のノードにフェイルオーバーします。フェイルオーバーが失敗すると、エラーメッセージを記録し、検証プログラムを状態 1 (失敗) で終了します。
再試行時間が再試行最大期間を過ぎておらず、再試行カウンタが再試行最大回数を超えていない場合、データサービスをローカルで再起動します。エラーメッセージを記録し、retries 変数の再試行カウンタをインクリメントします。
期限 (再試行最大期間) 内に再起動の回数 (再試行カウンタ) が制限 (再試行最大回数) に到達した場合、この関数は、RGM がデータサービスを別のノードに再配置することを要求します。再起動の回数が制限に到達していない場合、あるいは、再試行最大期間を過ぎていて、再試行カウンタをリセットする場合、この関数は DNS を同じノード上で再起動しようとします。
この関数については、次の点に注意してください。
gettime ユーティリティーを使用すると、再起動間の時間を追跡できます。これは C プログラムで、(RT_basedir ) ディレクトリ内にあります。
Retry_count と Retry_interval のシステム定義リソースプロパティーは、再起動を行う回数と期間を決定します。RTR ファイルでは、これらのプロパティーのデフォルト値は、再試行が 2 回、期間が 5 分 (300 秒) ですが、クラスタ管理者はこれらの値を変更できます。
restart_service() 関数は、同じノード上でデータサービスの再起動を試行する場合に呼び出されます。この関数の詳細については、次の節である「データサービスの再起動」を参照してください。
scha_control() API 関数を SCHA_GIVEOVER 引数付きで実行すると、サンプルデータサービスのあるリソースグループがオフラインになり、別ノード上でオンラインに戻ります。
restart_service() 関数は、decide_restart_or_failover() によって呼び出され、同じノード上でデータサービスの再起動を試行します。
この関数は次の作業を行います。
データサービスがまだ PMF 下に登録されているかどうかを判別します。
サービスがまだ登録されている場合、この関数は次の作業を行います。
データサービスの Stop メソッド名と Stop_timeout 値を取得します。
hatimerun を使用してデータサービスの Stop メソッドを起動し、Stop_timeout 値を渡します。
データサービスが正常に停止した場合は、データサービスの Start メソッド名と Start_timeout 値を取得します。
hatimerun を使用してデータサービスの Start メソッドを起動し、Start_timeout 値を渡します。
データサービスが PMF 下に登録されていない場合は、データサービスが PMF 下で許可されている再試行最大回数を超えていることを示しています。scha_control コマンドが GIVEOVER 引数付きで実行され、それによってデータサービスが別のノードにフェイルオーバーします。
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 プログラムはエラー状態で終了します。このプログラムは「Failover attempt failed」(フェイルオーバーは失敗しました) というメッセージを記録します。
RGM は、サンプルデータサービスがオンラインになったあとに、Monitor_start メソッドを呼び出して dns_probe メソッドを起動します。
この節では、サンプルアプリケーションの Monitor_start メソッドの重要な部分だけを説明します。parse_args() 関数など、すべてのコールバックメソッドに共通な機能については説明しません。また、syslog() 関数の使用法についても説明しません。共通の機能については、「すべてのメソッドに共通な機能の提供」を参照してください。
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
RGM は、サンプルデータサービスがオフラインになるときに、Monitor_stop メソッドを呼び出して dns_probe の実行を停止します。
この節では、サンプルアプリケーションの Monitor_stop メソッドの重要な部分だけを説明します。parse_args() 関数など、すべてのコールバックメソッドに共通な機能については説明しません。また、syslog() 関数の使用法についても説明しません。共通の機能については、「すべてのメソッドに共通な機能の提供」を参照してください。
Monitor_stop メソッドの完全なリストについては、「Monitor_stop メソッドのコードリスト」を参照してください。
このメソッドは、PMF (pmfadm) を使用して検証プログラムが動作しているかどうかを判断し、動作している場合は検証プログラムを停止します。
Monitor_stop メソッドは、pmfadm -q を使用して検証プログラムが動作しているかどうかを判断し、動作している場合は pmfadm -s を使用して検証プログラムを停止します。検証プログラムがすでに停止している場合でも、このメソッドは成功状態でします。これによって、メソッドが呼び出し回数に依存しないことが保証されます。
必ず KILL シグナルと pmfadm を使用して検証プログラムを停止してください。TERM などのマスク可能なシグナルは使用しないでください。そうしないと、Monitor_stop メソッドが無限にハングし、結果としてタイムアウトする可能性があります。これは、データサービスを再起動またはフェイルオーバーする必要がある場合に PROBE メソッドは scha_control() を呼び出すためです。データサービスをオフラインにするプロセスの一部として scha_control() が Monitor_stop を呼び出す場合、Monitor_stop がマスクできるシグナルを使用すると、Monitor_stop は scha_control() の完了を待機してハングし、scha_control() は 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
PROBE メソッドを停止できない場合、Monitor_stop メソッドはエラーメッセージを記録します。RGM は、主ノード上でサンプルのデータサービスを MONITOR_FAILED 状態にするため、そのノードに障害が発生することがあります。
Monitor_stop メソッドは、検証プログラムが停止するまで終了してはなりません。
データサービスが含まれるリソースグループを 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 の値を取得します。Monitor_check は、次のように、この値を 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 メソッドの仕組み」を参照してください。