Zabbix Agentのプロセスを調べてみた

Zabbix AgentにはActiveチェックとPassiveチェックの2つの方法で監視を行う仕組みが備わっています。
PassiveチェックはZabbixServerからZabbixAgentに対してアイテムキーを送り、そのアイテムキーに該当する監視結果をZabbix AgentからZabbix Serverに返す仕組みです。
一方、Activeチェックは、次の仕組みで実現されます。

  1. Zabbix AgentからZabbix Serverに対して、どういった項目を監視すればいいのかを示したアイテムリストを送付するよう要求
  2. 取得したアイテムリストの内容に従ってZabbix Agentが監視を実施
  3. 監視結果を以下のような形式のデータとしてZabbix Serverに送付
{ "request":"agent data", "data":[ { "host":"", "key":"log[\/home\/zabbix\/logs\/zabbix_agentd.log]", "value":" 13039:20090907:184546.759 zabbix_agentd started. ZABBIX 1.6.6 (revision {7836}).", "lastlogsize":80, "clock":1252926015 }, { "host":"", "key":"agent.version", "value":"1.6.6", "clock":1252926015 } ], "clock":1252926016 }

※Zabbix公式マニュアルより引用:Zabbix2.0マニュアル

このような仕組みの違いがあります。

今回気になったのは、Zabbix Agentの設定ファイル内のStartAgentsの項目です。
StartAgentsの説明は次のように書かれています。

Number of pre-forked instances of zabbix_agentd that process passive checks.
If set to 0, disables passive checks and the agent will not listen on any TCP port.

StartAgentsで設定できるのはPassiveチェック用スレッドの数だけのようです。

では、Activeチェック用のスレッドはどうなっているのか?
ということでZabbixAgentのソースコードを眺めてみました。
(今回調査したのはZabbix2.0.5のソースコードです。)

Zabbixは3つの種類のスレッドで成り立っています。

  1. collectorスレッド
  2. listenerスレッド
  3. active_checksスレッド

1はZabbixAgentが稼働するサーバ内のCPUやメモリ等のリソース情報を収集するスレッドです。これはソースコード内で1個と指定されています。
2はStartAgentsで数を設定するPassiveチェック用の待受スレッドです。StartAgentsで指定した数だけ稼働します。ZabbixServerからより頻繁に問い合わせを行うなど負荷が気になる場合にはStartAgentsの数を増やすことで対応できます。
3はActiveチェック用のスレッドです。ソースコードを見ると、active_checksスレッドの数については次のように決められているようでした。

src/zabbix_agent/zabbix_agentd.c

286行目
static int      add_activechk_host(const char *host, unsigned short port)
{
        int     i;

        for (i = 0; i < CONFIG_ACTIVE_FORKS; i++)
        {
                if (0 == strcmp(CONFIG_ACTIVE_ARGS[i].host, host) && CONFIG_ACTIVE_ARGS[i].port == port)
                        return FAIL;
        }

        CONFIG_ACTIVE_FORKS++;
        CONFIG_ACTIVE_ARGS = zbx_realloc(CONFIG_ACTIVE_ARGS, sizeof(ZBX_THREAD_ACTIVECHK_ARGS) * CONFIG_ACTIVE_FORKS)
;
        CONFIG_ACTIVE_ARGS[CONFIG_ACTIVE_FORKS - 1].host = zbx_strdup(NULL, host);
        CONFIG_ACTIVE_ARGS[CONFIG_ACTIVE_FORKS - 1].port = port;

        return SUCCEED;
}

311行目
static void     get_serveractive_hosts(char *active_hosts)
{
        char    *l = active_hosts, *r;
        int     rc = SUCCEED;

        do
        {
                char            *host = NULL;
                unsigned short  port;

                if (NULL != (r = strchr(l, ',')))
                        *r = '\0';

                if (SUCCEED != parse_serveractive_element(l, &host, &port, (unsigned short)ZBX_DEFAULT_SERVER_PORT))
                        goto fail;

                rc = add_activechk_host(host, port);

CONFIG_ACTIVE_FORKSが稼働するactive_checksスレッドの数の設定です。
0からスタートし、Activeチェックホストの設定毎に1つ加算されるようになっています。

zabbix_agentd.confの設定でServerActive=hostname1:10051,hostname2:10051のようにカンマ区切りで対象のZabbixServerを複数指定することができます。
(※このActive監視のマルチサーバサポートはZabbixの1.8.12より実装されています。BlueSkyDetectorさんのslideshare, Zabbix Blog)
どうやらこのサーバの設定1つにつき1スレッドを立ち上げて処理を行うような仕組みになっているようです。

StartAgents=3
ServerActive=hostname1,hostname2
と設定した上でZabbixAgentを起動すると、
zabbix_agentd.logに以下のログが追記され、listnerスレッドが3個、active_checksスレッドが2個、collectorスレッドが1個起動しているのがわかります。

  1801:20130305:072636.607 agent #1 started [listener]
  1802:20130305:072636.607 agent #2 started [listener]
  1803:20130305:072636.607 agent #3 started [listener]
  1805:20130305:072636.608 agent #5 started [active checks]
  1804:20130305:072636.608 agent #4 started [active checks]
  1800:20130305:072636.609 agent #0 started [collector]

今回はここまで。
ここから先の具体的な処理内容はまた時間がある時にでも見てみようと思います。