在 Linux 上有一个大家用惯的 systemd,在 MacOS 上有一个与之相对应的工具,launchd。
Linux 下,systemd 的 pid 是 1,系统启动后,它是第一个被拉起来的,其它进程都是它的子进程。所以在 Linux 下,用 systemd 来做 supervisor 是最稳妥的办法。因为如果 systemd 挂掉了,整个系统都 crash 了。
MacOS 下面也有一个这样的超级进程,所有的其它进程都是它产生的,挂为它的子进程、孙子进程…… 它就是 launchd。launchd 对应的管理工具就是 launchctl。
1. 原理
通过后缀名为 .plist
的配置文件追加 launchd 的管理项。添加和删除,都是用 .plist
文件来完成的。
.plist
文件存在于下面的文件夹中,分别是。
类型 | 路径 | 说明 |
---|---|---|
User Agents | ~/Library/LaunchAgents |
为当前登录用户启动 |
Global Agents | /Library/LaunchAgents |
为当前登录用户启动 |
Global Daemons | /Library/LaunchDaemons |
root 或者通过 UserName 配置指定的用户 |
System Agents | /System/Library/LaunchAgents |
当前登录用户 |
System Daemons | /System/Library/LaunchDaemons |
root 或者通过 UserName 配置指定的用户 |
按照需要将你要监控的程序放到不同等级的目录中。
2. 配置
Label
com.simonkuang.macos.coredns
Disabled
KeepAlive
ProcessType
Background
ProgramArguments
/usr/local/bin/coredns
-conf
/usr/local/etc/Corefile
UserName
root
GroupName
wheel
上面的例子是启动一个 coredns 进程。启动的命令如下。
/usr/local/bin/coredns -conf /usr/local/etc/Corefile
配置中的项目包括。
-
Label
: 应该是唯一的 package name。 -
Disabled
: 是否不生效(launchd 忽略,不执行) -
KeepAlive
: 意外挂掉的话,是否由 launchd 重新拉起。 -
ProcessType
: 进程类型。 -
ProgramArguments
: 程序参数。 -
UserName
: 启动进程的用户。 -
GroupName
: 启动进程的用户组。
因为 coredns 会启动 53/udp 端口的监听,53 < 1024,因此我们需要给它 root 用户的权限。因为 dns 是基础网络服务,因此以系统进程的方式启动。所以该配置文件按下面的路径保存。
/Library/LaunchDaemons/com.simonkuang.macos.coredns.plist
请注意,文件名和 Label 保持一致。
3. 操作
# 加载配置
launchctl load -w /Library/LaunchDaemons/com.simonkuang.macos.coredns.plist
# 卸载配置
launchctl unload /Library/LaunchDaemons/com.simonkuang.macos.coredns.plist
# 修改配置后重载配置
launchctl unload /Library/LaunchDaemons/com.simonkuang.macos.coredns.plist && \
launchctl load -w /Library/LaunchDaemons/com.simonkuang.macos.coredns.plist
-w
参数的意思是,无论配置中 Disabled
项是 true 还是 false,都启动进程。这个参数对调试配置和进程特别有效。
加载成功的服务,系统重启后会按照配置运行,达到 supervisor 的目的。
4. 更多
# 查看所有的 plist 服务
launchctl list
# 禁用服务
launchctl disable /Library/LaunchDaemons/com.simonkuang.macos.coredns.plist
# 启用服务
launchctl disable /Library/LaunchDaemons/com.simonkuang.macos.coredns.plist
# 杀死进程(不优雅地杀,直接杀进程)并重启服务。对一些停止响应的服务有效。
launchctl kickstart -k /Library/LaunchDaemons/com.simonkuang.macos.coredns.plist
# 在不修改 Disabled 配置的前提下启动服务
launchctl start /Library/LaunchDaemons/com.simonkuang.macos.coredns.plist
# 在不修改 Disabled 配置的前提下停止服务
launchctl stop /Library/LaunchDaemons/com.simonkuang.macos.coredns.plist