DSDL を使用したリソースタイプ実装には、通常、次の役割を実行する障害モニターデーモンがあります。
管理されているアプリケーションの状態を定期的に監視します。モニターデーモンのこの役割は特定のアプリケーションに大きく依存し、リソースタイプによって大幅に異なることがあります。DSDL には、TCP に基づく簡単なサービスの状態を検査するいくつかのユーティリティー関数が組み込まれています。HTTP、NNTP、IMAP、POP3 など、ASCII ベースのプロトコルを使用するアプリケーションは、これらのユーティリティーを使って実装できます。
アプリケーションによって検出された問題を、リソースプロパティー Retry_interval や Retry_count を使って追跡します。 さらに、アプリケーションが完全に異常停止した場合、障害モニターは、PMF アクションスクリプトを使ってサービスを再起動すべきかどうかや、アプリケーションの障害が急速に蓄積されるためにフェイルオーバーを実行する必要があるかどうかを判断する必要があります。DSDL のユーティリティー scds_fm_action() と scds_fm_sleep() は、この機構の実装を助けることを目的としています。
一般に、アプリケーションを再起動するか、リソースを含むリソースグループのフェイルオーバーを試みるなど、適切なアクションを実行します。DSDL ユーティリティー scds_fm_action() には、このアルゴリズムが実装されています。このユーティリティーは、この目的のために、過去の Retry_interval 秒数の間に起った検証障害の現在の累積を計算します。
リソースの状態を更新します。これによって、Sun Cluster の管理コマンドやクラスタ管理 GUI からアプリケーションの状態を知ることができます。
DSDL ユーティリティーの設計では、障害モニターデーモンの主要ループは、この節の最後にある擬似コードで表すことができます。
DSDL を使用して障害モニターを実装する際には、次の点に注意してください。
アプリケーションプロセスの異常停止は、scds_fm_sleep() によって迅速に検出されます。 これは、PMF によるアプリケーションプロセス停止の通知が非同期に行われるためです。そのため、障害の検出時間が大幅に短くなり、サービスの可用性が高くなります。別の方法としては、障害モニターが頻繁にスリープから復帰してサービスの状態を検査し、アプリケーションプロセスの停止を検出する方法があります。
RGM が scha_control API によるサービスのフェイルオーバーを拒否すると、scds_fm_action() は、現在の障害履歴を「リセット」(消去) します。この関数が現在の障害履歴をリセットするのは、障害履歴が Retry_count の値をすでに超えているからです。モニターデーモンは、次のサイクルでスリープから復帰したあとに、デーモンの状態検査を正常に完了できないと、scha_control() 関数を再び呼び出そうとします。しかし、前回のサイクルで呼び出しが拒否され状況が依然として残っていれば、この呼び出しは今回も拒否されるはずです。履歴がリセットされていれば、障害モニターは、少なくとも、次のサイクルでアプリケーションの再起動などによってその状況を内部的に訂正しようとします。
再起動が失敗に終わった場合、scds_fm_action() は、アプリケーション障害履歴をリセットしません。これは、状況が訂正されなければ、scha_control() が間もなく呼び出される可能性が高いからです。
ユーティリティー scds_fm_action() は、障害履歴に従って、リソースステータスを SCHA_RSSTATUS_OK、SCHA_RSSTATUS_DEGRADED、SCHA_RSSTATUS_FAULTED のどれかに更新します。その結果、このステータスをクラスタシステム管理から使用できるようになります。
ほとんどの場合、アプリケーション固有の状態検査アクションは、スタンドアロンの別個のユーティリティー (たとえば、svc_probe()) に実装できます。これは、次の汎用的なメインループに統合できます。
for (;;) {
/* 正常な検証と検証の間の thorough_probe_interval
* だけスリープする。
*/
(void) scds_fm_sleep(scds_handle,
scds_get_rs_thorough_probe_interval(scds_handle));
/* 使用するすべての ipaddress を検証する。次の各要素を繰り返し検証する。
* 1. 使用するすべてのネットリソース
* 2. 特定のリソースのすべての ipaddresses
* 検証する ipaddress ごとに
* 障害履歴を計算する。
*/
probe_result = 0;
/* すべてのリソースを繰り返し調べて、
* svc_probe() の呼び出しに使用する各 IP アドレスを取得する。
*/
for (ip = 0; ip < netaddr->num_netaddrs; ip++) {
/* 状態を検証する必要があるホスト名とポート
* を取得する。
*/
hostname = netaddr->netaddrs[ip].hostname;
port = netaddr->netaddrs[ip].port_proto.port;
/*
* HA-XFS は、1 つのポートしかサポートしないため
* ポート配列の最初のエントリから
* ポート値を取得する。
*/
ht1 = gethrtime();
/* Latch probe start time */
probe_result = svc_probe(scds_handle, hostname, port, timeout);
/*
* サービス検証履歴を更新し、
* 必要に応じてアクションを実行する。
* 検証終了時刻を保存する。
*/
ht2 = gethrtime();
/* ミリ秒に変換する。 */
dt = (ulong_t)((ht2 - ht1) / 1e6);
/*
* 障害履歴を計算し、
* 必要に応じてアクションを実行する。
*/
(void) scds_fm_action(scds_handle,
probe_result, (long)dt);
} /* 各ネットワークリソース */
} /* 検証を続ける */