systemd重載和hypnotoad重載需要一個包裝腳本一起工作正常
注:此解決方法適用於Mojolicious 6.x中SystemD兼容性固定在Mojolicious 7.x中
如果你想要下systemd重新加載,則一個標準的hypnotoad重載(即hypnotoad myapp.pl
)或kill -USR $MAINPID
不preferrable。 SystemD假定一旦重新加載hypnotoad服務器的命令返回,重新加載完成。但是,相反,這兩個選項都會立即退出,並且不會等待重新加載完成。
當我嘗試了這些標準重新加載選項時,systemd完成重新裝入命令的執行,然後監視pid文件被刪除並在hypnotoad執行「開始零停機軟件升級>升級成功」 。
如果您已將systemd配置爲始終運行hypnotoad應用程序,那麼systemd將再次重新啓動(停止並啓動)應用程序 - hypnotoad正常工作後。
這裏是發生了什麼:
- systemd重裝hypnotoad-應用(ExecReload = hypnotoad myapp.pl)被告知要重新加載
- hypnotoad後
- hypnotoad,應用程序退出啓動一個新的進程與最新的myapp。pl
- systemd認爲重新加載剛剛完成,並且看到pid沒有在PIDFile中變化hypnotoad在舊進程中看不到負載,殺死它們並刪除並創建一個新的PIDFile,其中新(這是hypnotoad的「零宕機時間」重新加載過程)
- systemd發現刪除了pid文件(它忽略了它被重新創建,可能是因爲通過設計,systemd想要控制分叉)
- systemd等待HOLDOFF(
RestartSec=<seconds>
)(如果已配置)
- systemd執行hyp的全部單位開始notoad-應用
systemd文件明確指出,當ExecReload=
命令返回,systemd預計過程已經完成重裝,和pid文件有重裝過程的新PID。但Hypnotoad不能像這樣同步工作。所以systemd和hypnotoad不能很好地協同工作。
https://www.freedesktop.org/software/systemd/man/systemd.service.html
注意然而,通過發送一個信號(如與上面的 例如線)重裝守護程序通常不是一個很好的選擇,因爲這是一個 異步操作,因此不適合訂購互相重新加載 多種服務。強烈建議 將ExecReload =設置爲一個命令,該命令不僅會觸發配置 重新加載守護進程,還會同步等待它完成。
解決方法是在重新加載過程中編寫一個包裝。
#!/bin/bash
SERVER="/path/to/myapp.pl"
HYPNOTOAD="/usr/bin/hypnotoad"
PIDFILE="/var/run/myapp.pid"
# Timeout == LOOPSAFE x SLEEPTIME
SLEEPTIME="0.5"
LOOPSAFE=20
LOOPCOUNT=0
#
if [ ! -f "${PIDFILE}" ]; then
# The PID files does not exist, maybe $SERVER is not running
exit 1
fi
OLDPID=$(cat ${PIDFILE})
NEWPID=$OLDPID
# Reload the application
${HYPNOTOAD} ${SERVER}
while (($LOOPCOUNT <= $LOOPSAFE)); do
let LOOPCOUNT++
if [ -f ${PIDFILE} ]; then
NEWPID=$(cat ${PIDFILE})
if (($NEWPID > 1)) && (($NEWPID != $OLDPID)); then
exit 0
fi
fi
sleep ${SLEEPTIME}
done
exit 1
這裏是需要Hypnotoad的systemd單元文件
[Unit]
Description=Hypnotoad-app
Requires=network.target
After=network.target
[Service]
Type=simple
SyslogIdentifier=hypnotoad-app
PIDFile=/var/run/myapp.pid
EnvironmentFile=-/etc/sysconfig/myapp
ExecStart=/usr/bin/hypnotoad --foreground /path/to/myapp.pl
ExecStop=/usr/bin/hypnotoad --stop /path/to/myapp.pl
ExecReload=/path/to/reload-myapp.sh
KillMode=process
Restart=always
RestartSec=5
User=myuser
Group=mygroup
[Install]
WantedBy=multi-user.target
這裏是重裝過程現在是如何工作的
- systemd重裝hypnotoad-應用
- systemd執行重裝腳本
- 重載腳本重新載入hypnotoad-app,並等待「s成功升級「 - 基本上處於休眠狀態,直到PID文件具有新重新加載的myapp的PID。P1方法
- systemd現在監視與新的PID,這不會改變任何更多的pid文件 - 所以現在systemd不會嘗試重新啓動它
不需要這條線。 –