agent.ping + nodata() で問題ありませんか?【MIRACLE ZBX 1.8, 2.0, 2.2】
agent.ping + nodata() の罠?
Zabbixエージェントの死活を調べるために、agent.pingキーとトリガー関数nodata()を使用することが推奨されています。けれども、当社ではnet.tcp.portキー(外部チェック)を推奨しています。
agent.pingのどこがよくない?
まずはagent.pingの実装を見てみましょう。
agent.pingに関する実装は、src/libs/zbxsysinfo/agent/agent.cにあり、対応する関数はAGENT_PING()となります。
49 static int AGENT_PING(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result)
50 {
51 SET_UI64_RESULT(result, 1);
52
53 return SYSINFO_RET_OK;
54 }
至ってシンプルな実装です。
Zabbixエージェントが(TCP接続されてから)要求を読み取った後に、キーに対応する関数AGENT_PING()
をコールし、そこでresultに1をセットするだけです。後は、Zabbixサーバにresultを返すだけです。
では、どこがよくないのでしょう?
それは、値として1しかセットされないことです。
トリガー判定はいつ行われるの?
Zabbix内でトリガー判定が行われるタイミングは実は二通りあります。
1. アイテムのデータを取得した後に、キャッシュからDBへ書き込むとき(History Syncerプロセス)
2. タイマー系関数を含んでいるものは30秒に一度(Timerプロセス)
Zabbixサーバ内では取得したアイテムデータを一度キャッシュへ置き、その後History Syncerプロセス(DB Syncerともいいます)により、DBへ書き込みます。ですが、上記のようにagent.pingは1という値しかしません。ですので、このタイミングで値によるトリガー式の評価が有効ではありません。結果として、nodata()のようなタイマー系関数を用い、どれくらいの期間取得していないかというような判定を、Timerプロセスにより行わなくてはなりません。
上記のDBへの書き込み処理はサーバ全体の負荷に左右され、遅延が発生することがあります。遅延が発生している状態でも、Timerプロセスは(ほぼ必ず)30秒に一度評価を行います。これによりagent.pingの値の取得自体には問題がないにもかかわらず、書き込み遅延が発生しているためトリガー評価は真(問題が発生している)となることがあります。
では、シンプルチェック net.tcp.serviceは?
シンプルチェック net.tcp.serviceは、対象となるホストの特定のポートに接続を試みるだけのキーです。
しかし、なんとこのキーは接続に失敗したときに FAILED がセットされます。つまり net.tcp.service を使用するときのトリガー関数において失敗したかどうかを判別することができるのです。このため agent.ping + nodata() のような評価の食い違いは起こりません。
※ agent.pingのように、Zabbixエージェント自身が返信するわけではありませんが、そのこと自体にはほとんど問題はありません。
このような理由で当社ではnet.tcp.serviceの使用を推奨しています。
2015/08/26 net.tcp.serviceをnet.tcp.portと誤って記述しておりましたので修正しました。また、1.8系ではnet.tcp.serviceキーではなく、tcpキーを使用してください。