在 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. 配置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.simonkuang.macos.coredns</string>
<key>Disabled</key>
<false/>
<key>KeepAlive</key>
<true/>
<key>ProcessType</key>
<string>Background</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/coredns</string>
<string>-conf</string>
<string>/usr/local/etc/Corefile</string>
</array>
<key>UserName</key>
<string>root</string>
<key>GroupName</key>
<string>wheel</string>
</dict>
</plist>
上面的例子是啓動一個 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