Ervaart u regelmatig crashes van Apache2 met HestiaCP? Monit biedt een geautomatiseerde monitoring- en probleemoplossingshandleiding (inclusief volledige configuratie).

HestiaCP 环境下 Apache2 频繁崩溃或 Monit 自动重启失效?本文为你总结 Monit 监控 Apache2 的实战避坑指南,深度剖析 PID 路径错位、权限阻断等常见坑点,并提供生产级 Monit 自动化配置文件。立即掌握服务器高可用运维技巧,实现故障秒级自动恢复!

Monit 监控 Apache2 这件事,我踩的坑

上周五,服务器半夜给我弹了个 Monit 告警。

我迷迷糊糊看了一眼面板,apache2 状态一栏,红色的 Timeout。

Ervaart u regelmatig crashes van Apache2 met HestiaCP? Monit biedt een geautomatiseerde monitoring- en probleemoplossingshandleiding (inclusief volledige configuratie).

我寻思了一下,白天刚给服务器加了个 Monit 监控,按照网上的教程复制粘贴的配置,照理说应该没啥问题啊。

结果第二天早上一看,又 Timeout 了。第三次之后,Monit 直接摆烂,面板上显示 Not monitored。

I...

我承认,一开始我是真没当回事。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。你照着做,错的不是你,是信息源本身就有问题。

Ervaart u regelmatig crashes van Apache2 met HestiaCP? Monit biedt een geautomatiseerde monitoring- en probleemoplossingshandleiding (inclusief volledige configuratie).

Apache2 PID文件损坏导致Monit误判进程不存在

把端口从 80 改成 8081 之后,Monit 理论上应该能探测到了对吧。

但实际情况是,偶尔还是会报 Execution failed。

我折腾了半天,最后发现原因很简单,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 一下看看文件内容,里面应该是一串数字,不是空的。

这一步做完,基本就解决了。

Ervaart u regelmatig crashes van Apache2 met HestiaCP? Monit biedt een geautomatiseerde monitoring- en probleemoplossingshandleiding (inclusief volledige configuratie).

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 次,留足容错空间。

HestiaCP Monitor monitoring配置踩坑总结与经验分享

配置改完之后,我 monitor apache2 了一下,面板上终于显示绿色的 OK 了。

当时的心情怎么说呢,就是那种你花了两天时间跟一个 Bug 较劲,最后发现原因就是一行配置写错了。哭笑不得。

Monit 本身是个好东西,监控守护进程这件事,确实是每个服务器都该做的。但问题就在于,网上太多教程是基于「Apache2 独占 80 端口」这个假设写的,而 HestiaCP 用了反向代理,这个假设就不成立了。

你照着做,错的不是你,是那个教程的适用场景跟你不一样。

所以如果你也在用 HestiaCP,也在折腾 Monit 监控 Apache2,记住两件事就行。端口改成 8081,停止命令用 systemctl 别用 killall -9。做到这两点,基本上就不会再出幺蛾子了。


Aangezien je tot hier hebt gelezen, en je het nuttig vond, geef het dan een like en deel het. Wil je als eerste op de hoogte blijven van de laatste ontwikkelingen, volg me dan!

Bedankt voor het lezen van mijn artikel. Tot de volgende keer.

发表 评论

Uw e-mailadres wordt niet gepubliceerd. 必填 项 已 用 * 标注

Scroll naar boven