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 で指定した秒数の間に起った検証障害の累積を計算します。
リソースの状態を更新します。これによって、scstat コマンドやクラスタ管理 GUI からアプリケーションの状態を知ることができます。
DSDL ユーティリティーの設計では、障害モニターデーモンの主要ループは次のようになっています。
DSDL を使って実装された障害モニターでは、
アプリケーションプロセスの異常停止は、scds_fm_sleep() によって比較的迅速に検出されます。これは、PMF によるプロセス停止の通知が非同期に行われるためです。これは、障害モニターが時々リープから復帰してサービスの状態を検査し、アプリケーションの停止を検出する方法と対象的です。DSDL を使用した障害モニターでは障害検出時間が大幅に短縮されるため、サービスの可用性が向上します。
RGM が scha_control(3HA) 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); } /* 各ネットワークリソース */ } /* 検証を続ける。*/ |