HestiaCP Apache2 頻繁崩潰? Monit 自動化監控與避坑指南(附完全設定)

HestiaCP環境下Apache2 頻繁崩潰或Monit 自動重啟失效?本文為你總結Monit 監控Apache2 的實戰避坑指南,深度剖析PID 路徑錯位、權限阻斷等常見坑點,並提供生產級Monit 自動化設定檔。立即掌握伺服器高可用運維技巧,實現故障秒自動恢復!

Monit 監控Apache2 這件事,我踩的坑

上週五,伺服器半夜給我彈了個Monit 告警。

我迷迷糊糊看了一眼面板,apache2 狀態一欄,紅色的Timeout。

HestiaCP Apache2 頻繁崩潰? Monit 自動化監控與避坑指南(附完全設定)

我尋思了一下,白天剛給伺服器加了個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。你照著做,錯的不是你,是資訊來源本身就有問題。

HestiaCP Apache2 頻繁崩潰? Monit 自動化監控與避坑指南(附完全設定)

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 一下看看檔案內容,裡面應該是一串數字,不是空的。

這一步做完,基本上就解決了。

HestiaCP Apache2 頻繁崩潰? Monit 自動化監控與避坑指南(附完全設定)

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。要做到這兩點,基本上就不會再出么蛾子了。


以上,既然看到這裡了,如果覺得不錯,隨手點讚、轉發吧,如果想第一時間收到推送,也可以給我個關注~

謝謝你看我的文章,我們,下次再見。

發表評論

您的郵箱地址不會被公開。必填項已用*標註

回到頁首