Apache HTTP Server 版本2.2
本文檔敘述了在類Unix系統(tǒng)上如何停止和重啟Apache 。 Windows NT/2000/XP/2003的用戶請(qǐng)參見以服務(wù)方式運(yùn)行Apache ,Windows 9x/ME用戶則參見在控制臺(tái)中運(yùn)行Apache 。
為了停止或者重新啟動(dòng)Apache ,你必須向正在運(yùn)行的httpd
進(jìn)程發(fā)送信號(hào)。有兩種發(fā)送信號(hào)的方法。第一種方法是直接使用UNIX的kill
命令向運(yùn)行中的進(jìn)程發(fā)送信號(hào)。你也許你會(huì)注意到你的系統(tǒng)里運(yùn)行著很多httpd
進(jìn)程。但你不應(yīng)該直接對(duì)它們中的任何一個(gè)發(fā)送信號(hào),而只要對(duì)已經(jīng)在PidFile
中記載下了自身PID的父進(jìn)程發(fā)送信號(hào)。也就是說,你不必對(duì)父進(jìn)程以外的任何進(jìn)程發(fā)送信號(hào)。你可以向父進(jìn)程發(fā)送三種信號(hào):TERM
、HUP
、USR1
,我們過一會(huì)兒再進(jìn)行詳細(xì)的說明。
你可以用下面這樣的命令來向父進(jìn)程發(fā)送信號(hào):
kill -TERM `cat /usr/local/apache2/logs/httpd.pid`
第二種方法是使用下面將要描述的httpd
二進(jìn)制可執(zhí)行文件的 -k
命令行選項(xiàng):stop
、restart
、graceful
、graceful-stop
。不過我們推薦你使用apachectl
控制腳本來向httpd
二進(jìn)制可執(zhí)行文件傳遞這些選項(xiàng)。
當(dāng)你向httpd
發(fā)送信號(hào)后,你可以這樣來讀取它的進(jìn)行過程:
tail -f /usr/local/apache2/logs/error_log
你可以修改這些示例以適應(yīng)你的ServerRoot
和PidFile
設(shè)置。
apachectl -k stop
發(fā)送TERM
或stop
信號(hào)到父進(jìn)程可以使它立刻殺死所有子進(jìn)程。這將花費(fèi)一些時(shí)間來殺死所有子進(jìn)程。然后父進(jìn)程自己也退出。所有進(jìn)行中的請(qǐng)求將被強(qiáng)行中止,而且不再接受其它請(qǐng)求。
apachectl -k graceful
USR1
或graceful
信號(hào)使得父進(jìn)程建議子進(jìn)程在完成它們現(xiàn)在的請(qǐng)求后退出(如果他們沒有進(jìn)行服務(wù),將會(huì)立刻退出)。父進(jìn)程重新讀入配置文件并重新打開日志文件。每當(dāng)一個(gè)子進(jìn)程死掉,父進(jìn)程立刻用新的配置文件產(chǎn)生一個(gè)新的子進(jìn)程并立刻開始伺服新的請(qǐng)求。
重啟代碼的設(shè)計(jì)能夠確保MPM進(jìn)程控制指令的正常運(yùn)作,也就是在重啟過程中確保有適當(dāng)數(shù)量的進(jìn)程和線程以響應(yīng)客戶端的請(qǐng)求。它是這樣StartServers
的:如果在一秒鐘以后還沒有新創(chuàng)建StartServers
個(gè)子進(jìn)程,則創(chuàng)建出足夠完成現(xiàn)在任務(wù)的子進(jìn)程個(gè)數(shù)。因此,代碼除了保有能夠維持服務(wù)器的現(xiàn)有負(fù)載數(shù)量的子進(jìn)程外,也確保StartServers
按你的意愿運(yùn)作。
使用mod_status
的用戶會(huì)注意到在USR1
信號(hào)發(fā)出后,服務(wù)器的統(tǒng)計(jì)信息沒有被清零。代碼被寫成既能將你服務(wù)器無法伺服新請(qǐng)求的時(shí)間降至最少(這些請(qǐng)求將被操作系統(tǒng)放到隊(duì)列里,使得它們不會(huì)丟失),又能遵從你的參數(shù)優(yōu)化。為了做到這一點(diǎn),它將在重新生成子進(jìn)程的過程中,在scoreboard上保存所有子進(jìn)程的狀態(tài)。
mod_status
還會(huì)將那些在優(yōu)雅重啟前就已經(jīng)開始而沒有結(jié)束伺服請(qǐng)求的子進(jìn)程用一個(gè)"G
"來標(biāo)志。
目前,日志滾動(dòng)腳本還無法使用USR1
來確定所有寫入預(yù)重啟日志的子進(jìn)程都已結(jié)束。我們建議你在發(fā)出了USR1
信號(hào)后等待一個(gè)適當(dāng)?shù)臅r(shí)間,然后再對(duì)舊的日志做處理。比如說如果對(duì)于一個(gè)窄帶用戶來說,大部分的點(diǎn)擊處理將在10分鐘之內(nèi)完成,那么你應(yīng)該在處理舊的日志前等待15分鐘。
-t
命令行參數(shù)來檢查配置文件語(yǔ)法的正確性(參見httpd
)。但這仍然不能保證服務(wù)器一定可以正確的重啟。為了從語(yǔ)法和語(yǔ)義兩方面檢查配置文件,你可以用一個(gè)非root用戶來啟動(dòng)httpd
。如果沒有錯(cuò)誤,它將嘗試去打開套接字和日志文件,繼而因沒有root權(quán)限而失敗(或是因?yàn)楝F(xiàn)在運(yùn)行的httpd
已經(jīng)綁定了這些端口)。如果是因?yàn)槠渌蚰敲淳涂赡苁且粋(gè)配置文件產(chǎn)生的錯(cuò)誤,你就應(yīng)當(dāng)在進(jìn)行優(yōu)雅重啟之前改正這個(gè)錯(cuò)誤。apachectl -k restart
向父進(jìn)程發(fā)送HUP
或restart
信號(hào)會(huì)使它象收到TERM
信號(hào)一樣殺掉所有的子進(jìn)程,不同之處在于父進(jìn)程本身并不退出。它重新讀入配置文件、重新打開日志文件。然后產(chǎn)生一系列新的子進(jìn)程來繼續(xù)服務(wù)。
使用mod_status
的用戶會(huì)注意到在HUP
信號(hào)發(fā)出后,服務(wù)器統(tǒng)計(jì)信息會(huì)被清零。
apachectl -k graceful-stop
WINCH
或graceful-stop
信號(hào)使得父進(jìn)程建議子進(jìn)程在完成它們現(xiàn)在的請(qǐng)求后退出(如果他們沒有進(jìn)行服務(wù),將會(huì)立刻退出)。然后父進(jìn)程刪除PidFile
并停止在所有端口上的監(jiān)聽。父進(jìn)程仍然繼續(xù)運(yùn)行并監(jiān)視正在處理請(qǐng)求的子進(jìn)程,一旦所有子進(jìn)程完成任務(wù)并退出或者超過由GracefulShutdownTimeout
指令規(guī)定的時(shí)間,父進(jìn)程將會(huì)退出。在超時(shí)的情況下,所有子進(jìn)程都將接收到TERM
信號(hào)并被強(qiáng)制退出。
在"優(yōu)雅"狀態(tài)下,TERM
信號(hào)將會(huì)立即中止父進(jìn)程和所有子進(jìn)程。由于PidFile
已經(jīng)被刪除,你將無法使用apachectl
或httpd
發(fā)送該信號(hào)。
graceful-stop
允許你同時(shí)運(yùn)行多個(gè)相同配置的httpd
實(shí)例。這在對(duì)Apache進(jìn)行平滑升級(jí)的時(shí)候是一個(gè)非常有用的特性。不過它在某些配置的情況下同樣可能會(huì)導(dǎo)致死鎖和競(jìng)爭(zhēng)條件。
必須注意確保諸如Lockfile
和ScriptSock
之類的磁盤文件包含服務(wù)器的PID ,并且能夠安全的共存。然而如果一個(gè)配置指令、第三方模塊或持久CGI使用任何磁盤鎖或狀態(tài)文件,必須注意確保多個(gè)httpd
運(yùn)行實(shí)例之間不會(huì)爭(zhēng)搶文件。
你還必須防止?jié)撛诘母?jìng)爭(zhēng)條件,比如使用rotatelogs
風(fēng)格的管道日志。運(yùn)行中的多個(gè)rotatelogs
實(shí)例企圖同時(shí)滾動(dòng)同一個(gè)日志文件可能會(huì)導(dǎo)致互相破壞對(duì)方的日志文件。
在Apache 1.2b9 之前,有很多關(guān)于重啟和死亡信號(hào)的競(jìng)爭(zhēng)條件。關(guān)于競(jìng)爭(zhēng)條件的一個(gè)簡(jiǎn)單描述是:一個(gè)時(shí)間敏感的問題,如果一些事情在不適當(dāng)?shù)臅r(shí)間或以不恰當(dāng)?shù)捻樞虬l(fā)生,它將作出你不期望的反應(yīng);如果同樣的事情在恰當(dāng)?shù)臅r(shí)間發(fā)生,則不會(huì)出現(xiàn)異常。憑借那些擁有"正確"特性設(shè)置的體系結(jié)構(gòu),我們盡量避免了它們的出現(xiàn)。但值得注意的是,仍然有一些競(jìng)爭(zhēng)條件存在于這樣的體系結(jié)構(gòu)中。
使用物理磁盤的ScoreBoardFile
就有損壞ScoreBoard的潛在危險(xiǎn)。這將發(fā)生在"bind: Address already in use"(HUP
之后)或"long lost child came home!"(USR1
之后)時(shí)。前者是一個(gè)致命錯(cuò)誤,而后者則會(huì)使服務(wù)器丟失ScoreBoard的一個(gè)記錄。所以我們建議多使用優(yōu)雅重啟,偶爾使用硬重啟。這些問題很難解決,但幸運(yùn)的是大多數(shù)結(jié)構(gòu)并不需要ScoreBoard文件。而如果你需要這樣的結(jié)構(gòu),你可以參考ScoreBoardFile
文檔。
當(dāng)每個(gè)子進(jìn)程在一個(gè)HTTP的持續(xù)連接(KeepAlive)中涉及到第二個(gè)并發(fā)的請(qǐng)求時(shí),所有的結(jié)構(gòu)都會(huì)或多或少存在競(jìng)爭(zhēng)狀態(tài)的問題。它將在讀取了請(qǐng)求而沒有讀取任何請(qǐng)求頭之后立刻退出。這個(gè)修復(fù)對(duì)于1.2來說來得太晚了。但因?yàn)槌掷m(xù)連接的客戶端已經(jīng)考慮到網(wǎng)絡(luò)延時(shí)和服務(wù)器超時(shí)會(huì)造成類似的情況,所以理論上說,這不是一個(gè)太大的問題。而實(shí)際上似乎也沒有任何影響:在一個(gè)測(cè)試案例中服務(wù)器在一秒之內(nèi)被重啟了20次,而客戶端卻成功的瀏覽了網(wǎng)站,而且沒有任何破損的圖片或空文檔。