2012-06-21 85 views
3

我複製了中的systemdservice文件,並將其調整爲使systemd啓動mojolicious內置服務器守護進程。 我可以保留這個mojolicious守護進程的ExecReloadKillSignal設置嗎?如何重新加載mojolicious內置的webserver守護進程?

[Unit] 
Description=Start mojolicious.pl daemon 
After=syslog.target network.target 

[Service] 
ExecStart=/path/to/mojolicious.pl daemon --listen "http://*:3001" 
ExecReload=/bin/kill -HUP $MAINPID 
KillSignal=SIGINT 

[Install] 
WantedBy=multi-user.target 

回答

2

我不知道你爲什麼需要「重新加載」,當應用程序代碼改變時,Mojolicious會執行內部重新加載。你可能會替換到

/bin/kill -0 $MAINPID 

如果該行應該有,HUP將終端的正常應用(除非您處理不同的看法)

+0

不需要這條線。 –

5

我認爲亞歷克斯是思維的morbo時,他說,自動重載。對於生產,你最好使用hypnotoad。如果你切換到hypnotoad那麼有各種信號將是有用的。例如/bin/kill -USR2 $MAINPID將會優雅地重新加載,避免任何當前連接的擾亂。欲瞭解更多信號(hypnotoad)看到http://mojolicio.us/perldoc/Mojo/Server/Hypnotoad#SIGNALS

0

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不會嘗試重新啓動它
+0

我向hypnotoad提交了「--reload-wait」選項的錯誤/功能請求https://github.com/kraih/mojo/issues/1130 –

+0

將此問題的解決方案轉發到此處。這個問題在大約同一時間被注意到,文檔開始建議systemd並且它很快解決了。這個答案的海報使用的是過時的版本,沒有包含修正(版本7.01及以上版本應該可以)。 –

+0

我在CentOS 7上使用了Mojolicious 6.31。將Mojolicious升級到7.45,IO :: Socket :: IP> 0.37(0.37+不適用於CentOS 7的RPM)可以正常使用systemd。 –

0

另一種選擇是在前臺與-f &運行hypnotoad使用服務監督與runit &一個簡單的腳本/etc/sv/myapp/run

#!/bin/sh 

app=/path/to/my/app 
daemon=/path/to/hypnotoad 

exec 2>&1 
exec $daemon -f $app 

然後,您可以有hypnotoad重讀它與一個配置10

紅帽並不提供runit,但最新版本的rpm可以是built from here

不要忘記ln -s /etc/sv/myapp /etc/service/myapp使用runit啓用該服務。