试图了解launchd守护进程状态

时间:2018-04-25 14:37:29

标签: macos plist zabbix launchd macos-high-sierra

我正在尝试在macOS 10.13 High Sierra上为Zabbix代理设置一个launchd守护进程。

首先,我使用以下命令安装Zabbix代理:

brew install zabbix --without-server-proxy

然后我用这个内容创建一个名为com.zabbix.zabbix_agentd.plist的属性列表:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>AbandonProcessGroup</key>
        <true/>
        <key>GroupName</key>
        <string>zabbix</string>
        <key>KeepAlive</key>
        <dict>
                <key>SuccessfulExit</key>
                <false/>
        </dict>
        <key>Label</key>
        <string>com.zabbix.zabbix_agentd</string>
        <key>ProgramArguments</key>
        <array>
                <string>/usr/local/sbin/zabbix_agentd</string>
                <string>-c</string>
                <string>/opt/zabbix/zabbix_agentd.conf</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>StandardErrorPath</key>
        <string>/var/log/zabbix/zabbix_agentd.error.log</string>
        <key>StandardOutPath</key>
        <string>/var/log/zabbix/zabbix_agentd.stdout.log</string>
        <key>UserName</key>
        <string>zabbix</string>
</dict>
</plist>

我加载它:

sudo launchctl load ./com.zabbix.zabbix_agentd.plist

现在我可以看到该守护进程完成了我的预期:

ps ax | grep zabbix_agentd | grep -v grep

我看到了6个zabbix进程。 1个收集器,3个侦听器,1个活动检查以及启动守护程序启动的进程:

8931   ??  S      0:00.01 /usr/local/sbin/zabbix_agentd -c /opt/zabbix_agentd.conf

但是当我运行这个命令时:

launchctl print system/com.zabbix.zabbix_agentd | grep state

我得到了这个输出:

state = waiting

我希望看到state = running ...为什么该命令告诉我守护进程在有6个正在运行的进程时正在等待?

这是“按设计工作”还是我做错了什么?

1 个答案:

答案 0 :(得分:1)

这有点“按设计工作”,但我真的说这是zabbix和launchd之间关于守护进程应该如何工作的哲学冲突的结果。

当你运行zabbix_agentd时,它“daemonizes”本身,这意味着它会将实际的守护进程作为后台子进程触发,然后父进程退出;从那时起,守护进程(以及它启动的任何子进程)几乎独立于启动它们的任何操作。这几乎是unix守护进程运行的传统方式。

另一方面,

launchd被编写为期望它管理的守护进程保持在前台并直接在其下执行;这使得launchd能够监视和控制其守护进程的能力远远超过它们与launchd远离时的能力。

这是传统的unix守护进程和launchd之间的常见冲突,有两种方法可以解决它:要么让守护进程在前台运行(即遵循启动的做事方式),要么告诉launchd不要担心守护进程似乎已经退出。 zabbix_agentd似乎没有--nodaemon选项(根据these docs),所以你必须适应launchd(更新:更新的版本,见下文)。执行此操作的标准方法(就像您在.plist中所拥有的那样)是添加AbandonProcessGroupKeepAlive键以告诉launchd在(尽管它可以告诉)时不要惊慌守护进程退出。这有效,但这意味着launchd无法分辨守护进程实际发生的情况,导致您看到的结果看起来很奇怪。

更新:我正在查看旧版本的zabbix_agentd。 Stefan发现在version 3.0的zabbix_agentd中添加了-f(或--foreground)选项。有了这个,我建议将--foreground添加到ProgramArguments数组,用简单的KeepAlive替换<true/>字典(这告诉launchd自动重启守护进程,如果它出于任何原因退出),并删除<key>AbandonProcessGroup</key><true/>(此选项控制如果主守护程序进程退出/崩溃,launchd是否清除剩余的子进程)。结果应如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>GroupName</key>
        <string>zabbix</string>
        <key>Label</key>
        <string>com.zabbix.zabbix_agentd</string>
        <key>ProgramArguments</key>
        <array>
                <string>/usr/local/sbin/zabbix_agentd</string>
                <string>-c</string>
                <string>/opt/zabbix/zabbix_agentd.conf</string>
                <string>--foreground</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>KeepAlive</key>
        <true/>
        <key>StandardErrorPath</key>
        <string>/var/log/zabbix/zabbix_agentd.error.log</string>
        <key>StandardOutPath</key>
        <string>/var/log/zabbix/zabbix_agentd.stdout.log</string>
        <key>UserName</key>
        <string>zabbix</string>
</dict>
</plist>