在電腦世界,雖要有一些程式來管理其他程式的「啟動」、「重啟」及「停止」。
在 Windows、Linux、Matrix 🙂 都有。Windows 叫這做 “Services”。開放的 Linux 就有數種程式來做這種事。比較常用的就有 init、upstart 及 systemd。
現在知名的發行版,如 Fedora、RHEL、Ubuntu、Debian 都已把 init 改為用 systemd。這個轉換早前引發開源界很大爭議,原因 systemd 有違 Unix Philosophy:
- Write programs that do one thing and do it well.
- Write programs to work together.
- Write programs to handle text streams, because that is a universal interface
Systemd 做太多野了,不單啟動或重啟一個程式這樣簡單。Systemd 不是純 text process。對一般 users 來說 systemd 好處的確大過缺點,特別能並行啟動開機程式,令開機時間大大縮短,另外很多 software 如 GNOME3 依賴 systemd,所以好多發行版都改用了 systemd。
來看 init script,通常它是 BASH script,含有 programming 元素,用 case 來選擇 start、stop 及 restart command,而 restart 通常只是 stop 後再 start。
[bash]
start(){
# …
}
stop(){
# …
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
sleep 2
start
;;
*)
echo "Usage: $0 {start | stop | restart}"
esac
[/bash]
而 systemd script 則簡單得多,沒有 programming 元素,以 gorush 為例子,systemd script 就是這麼簡單易明。
[shell]
[Unit]
Description=A push notification micro server using Gin framework written in Go.
After=network.target
[Service]
# Run Grunt before starting the server (optional)
#
# Start the js-file starting the express server
ExecStart=/usr/local/bin/gorush -c /etc/gorush/gorush.yaml
WorkingDirectory=/var/lib/gorush
Restart=always
RestartSec=5
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=gorush
# Change to a non-root user (optional, but recommended)
User=gorush
Group=gorush
# Set environment options
#Environment=
[Install]
WantedBy=multi-user.target
[/shell]
把以上 script 放去 /lib/systemd/system/gorush.service
再用 systemctl 設定便可。
$ sudo systemctl daemon-reload
$ sudo systemctl enable gorush
$ sudo systemctl start gorush
最後,systemd 令人興奮的是,以往我們可能需要家一個 crontab
來不斷 monitor 個 process 有沒有掛掉,這個 systemd 都幫我們做了。
Restart=always
就是當 process 無論哪種原因,自然或不正常掛掉,都會 restart。除了 always,還有 no、on-success、on-failure、on-abnormal、on-abort、on-watchdog,詳細可看這裡。