文章目錄
HestiaCP環境下Apache2 頻繁崩潰或Monit 自動重啟失效?本文為你總結Monit 監控Apache2 的實戰避坑指南,深度剖析PID 路徑錯位、權限阻斷等常見坑點,並提供生產級Monit 自動化設定檔。立即掌握伺服器高可用運維技巧,實現故障秒自動恢復!
Monit 監控Apache2 這件事,我踩的坑
上週五,伺服器半夜給我彈了個Monit 告警。
我迷迷糊糊看了一眼面板,apache2 狀態一欄,紅色的Timeout。

我尋思了一下,白天剛給伺服器加了個Monit 監控,按照網路上的教學複製貼上的配置,照理說應該沒啥問題啊。
結果隔天早上一看,又Timeout 了。第三次之後,Monit 直接擺爛,面板上顯示Not monitored。
我。 。 。
我承認,一開始我是真沒當一回事。 Apache2 監控嘛,網路上一搜一大把的範本配置,Ctrl+C Ctrl+V 完事兒。結果這一粘,給我粘出了一肚子氣。
HestiaCP預設架構與Monit連接埠衝突的根源
先把那個害我不淺的配置放出來,大家感受一下,是不是跟你看過的版本一模一樣。
check process apache2 with pidfile /var/run/apache2/apache2.pid
start program = "/usr/sbin/service apache2 start"
stop program = "/usr/sbin/service apache2 stop"
if failed host 127.0.0.1 port 80 protocol http then restart
if 5 restarts within 5 cycles then timeout看起來沒啥問題對吧,偵測80 端口,掛了就重啟,重啟5 次還掛就timeout。
但問題是,你的Apache2 根本就不在80 埠上啊。
這就是HestiaCP 的一個坑,也是很多人踩進去的根源。 HestiaCP 預設的架構是Nginx + Apache2 的反向代理,前面Nginx 佔80 和443,後面Apache2 躺在本地的8081 連接埠上。
你讓Monit 去80 埠探測Apache2 的存活狀態,那就好比你去麥當勞找肯德基,服務生一臉懵逼地看著你,你倆大眼瞪小眼,最後Monit 判定你掛了,開始瘋狂重啟。
重啟完,連接埠還是8081,Monit 再去80 探測,還是失敗,再重開機。循環往復,直到Monit 覺得這貨沒救了,直接timeout。
我第一次遇到這個的時候,是真的愣住了。因為網路上搜出來的教程,十個有九個寫的都是port 80。你照著做,錯的不是你,是資訊來源本身就有問題。

Apache2 PID檔案損壞導致Monit誤判進程不存在
把連接埠從80 改成8081 之後,Monit 理論上應該可以偵測到了對吧。
但實際情況是,偶爾還是會報Execution f ai led。
我折騰了半天,最後發現原因很簡單,PID 檔案壞了。
你想想看,之前Monit 瘋狂重啟Apache2,每次都是暴力kill 再啟動,來回折騰好幾輪。在這個過程中,/var/run/apache2/apache2.pid 這個文件,有可能變成0 個位元組。
是說,文件還在,但裡面是空的。
Monit 讀這個文件的時候,唸出來個寂寞。它不認識你的Apache2,就算你的Apache2 好端端地在後台跑著呢,Monit 也覺得進程不存在。
我看到這個的時候,一時之間無語凝噎。
這玩意,就是一個死鎖。 Monit 偵測失敗,重啟Apache2,重啟過程弄壞了PID 文件,下次偵測又失敗,又重新啟動。循環直到timeout。
HestiaCP環境下Apache2監控的排除修復步驟
說實話,排查過程並不複雜,但你得知道往哪個方向查。
第一步,確認你的Apache2 到底監聽在哪個埠。在終端機敲一行命令就行。
netstat -tulpn | grep apache2或是用ss 指令,效果一樣。
ss -tulpn | grep apache2你會看到類似這樣的輸出。
tcp 0 0 127.0.0.1:8081 0.0.0.0:* LISTEN 2942372/apache2確認是8081,不是80。這就是問題的根源。
第二步,修復被搞壞的PID 檔案。這個比較簡單。
monit unmonitor apache2
systemctl restart apache2
cat /var/run/apache2/apache2.pid先暫停Monit 的監控,防止它在你修復的時候搗亂。然後重啟Apache2,讓它重新寫入一個乾淨的PID。最後cat 一下看看檔案內容,裡面應該是一串數字,不是空的。
這一步做完,基本上就解決了。

Monit傳統適配型與激進防護型配置比較分析
網路上關於Monit 設定Apache2 的教學課程,大致分為兩種。
一種是「傳統適配型」,就是用service 指令管理服務,偵測本地端口,不加太多花俏的限制。這種配置在HestiaCP 上改改連接埠就能用,比較穩。
另一種是「激進防護型」,用systemctl 管理服務,加子進程限制,檢測邏輯也更嚴格。看著很美,但有個致命傷,停止命令用的是killall -9。
killall -9 是什麼概念呢,就是不管你在幹什麼,直接強制殺死。這種暴力操作,容易留下損壞的PID 檔案。就是我剛才說的這個問題。
我個人的感受是,激進型配置裡的子進程限制確實有用,當你的Apache2 被CC 攻擊打滿的時候,限制子進程數量能防止伺服器記憶體爆炸。但killall -9 那套,是真的不能用。
所以最後我取了個折中,把兩種配置的優點拼在一起。
HestiaCP Apache2 Monit最佳實務設定方案
修改/etc/monit/conf.d/apache2 這個文件,內容如下。
check process apache2 with pidfile /var/run/apache2/apache2.pid
start program = "/bin/systemctl start apache2"
stop program = "/bin/systemctl stop apache2"
if children > 120 for 2 cycles then restart
if failed host 127.0.0.1 port 8081 protocol http for 2 cycles then restart
if 5 restarts within 10 cycles then timeout簡單說一下這幾行配置的邏輯。
埠寫8081,精準匹配HestiaCP 的反向代理架構,別再傻傻地寫80 了。
停止指令用systemctl stop,不用killall -9,這樣PID 檔案不會被搞壞。
加了一個子進程限制,children 大於120 連續兩個週期就重啟,防CC 攻擊,但不至於太激進。
偵測失敗的邏輯加了for 2 cycles,就是連續兩個週期都失敗才會觸發重啟,減少誤報。之前那個配置偵測一次就重啟,說實話有點神經質了。
最後的timeout 閾值放寬到10 個週期內重啟5 次,留足容錯空間。
赫斯提亞CP Monit監控配置踩坑總結與經驗分享
配置改完之後,我monitor apache2 了一下,面板上終於顯示綠色的OK 了。
當時的心情怎麼說呢,就是那種你花了兩天時間跟一個Bug 較勁,最後發現原因就是一行配置寫錯了。哭笑不得。
Monit 本身是個好東西,監控守護程式這件事,確實是每個伺服器都該做的。但問題就在於,網路上太多教學是基於「Apache2 獨佔80 埠」這個假設寫的,而HestiaCP 用了反向代理,這個假設就不成立了。
你照著做,錯的不是你,是那個教學的適用場景跟你不一樣。
所以如果你也在用HestiaCP,也在折騰Monit 監控Apache2,記住兩件事就好。埠改成8081,停止指令用systemctl 別用killall -9。要做到這兩點,基本上就不會再出么蛾子了。
以上,既然看到這裡了,如果覺得不錯,隨手點讚、轉發吧,如果想第一時間收到推送,也可以給我個關注~
謝謝你看我的文章,我們,下次再見。
希望陳溈亮部落格(https://www.chenweiliang.com/) 分享的《HestiaCP Apache2 頻繁崩潰? Monit 自動化監控與避坑指南(附完整配置)》,對您有幫助。
