ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

轻量级服务器监控利器Monit:进程守护与自动修复实战

轻量级服务器监控利器Monit:进程守护与自动修复实战 做服务器运维的朋友都应该有这种体会机器一多最怕的不是硬件故障而是某个进程悄悄挂了没人发现。特别是那种半夜定时任务跑完顺手把守护进程带崩的情况第二天早上打开电脑一看服务已经裸奔了好几个小时。我之前一直被这种问题折腾得够呛后来把Prometheus、Zabbix这些重型监控方案都试了一圈发现要么部署太重要么配置太复杂实在有点大材小用。直到用上Monit我才感觉找到了真正省心的方案——这套开源服务器监控工具轻量、配置直观、自带自动修复能力很适合个人服务器和小规模集群的维稳场景。这篇文章我就把自己从零配置Monit到实际落地的完整经验整理出来给还没入坑的朋友做个参考。1. Monit是什么它和其他监控方案有什么不一样1.1 先明确Monit的定位Monit是一个老牌的开源系统监控工具核心定位就是“监控加自动修复”。它用C语言写成安装之后就是一个独立的守护进程占用资源非常小。打个比方如果用Prometheus那套方案是给服务器装一套完整的医疗检测设备需要护士、医生、各种仪器协同工作那Monit就是一个随叫随到的社区医生日常帮你量血压、测体温发现问题当场就能开药处理。这种定位决定了Monit和主流监控方案走的是完全不同的路线。Prometheus这类时序监控平台擅长数据采集、历史查询、趋势分析配合Grafana能画出非常漂亮的图表但你要让它自动重启一个挂掉的进程还得额外配置Alertmanager和webhook链路相当长。Monit的思路则简单直接它持续检测指定的进程、端口、文件系统和系统资源一旦发现异常可以自动执行重启、停止、告警等操作不需要再依赖任何第三方组件。在实际部署中我的经验是把Monit当作服务的“最后一道保险”来用而不是替代Prometheus这类数据监控平台。需要看历史趋势、做容量规划的时候看Grafana需要确保进程活着、出问题能自动拉起的时候交给Monit两者配合反而比单用任一方案都更有安全感。1.2 核心能力拆解进程守护、资源监控、网络探测与文件系统监测Monit的功能项看起来不多但每一项都直指服务器运维的痛点。我把日常用到的能力整理成了下面的表格能力类型说明典型使用场景进程监控通过PID文件检测进程是否存活可配置启动/停止命令Nginx、MySQL、Redis等服务的保活系统资源监控监控CPU使用率、内存占用、负载均值防止某个进程吃满CPU导致机器卡死网络探测检测主机端口连通性支持HTTP、TCP、SMTP等协议确认Web服务是否真正响应而不仅仅是进程活着文件系统监控监控磁盘空间、文件属性、文件内容变化日志目录爆满前收到预警定时执行按周期执行自定义脚本或命令定期检查备份任务是否成功依赖管理通过depends on字段定义服务间的启动顺序先启动数据库再启动依赖数据库的应用这里最值得强调的是网络探测能力。很多监控工具只检测进程是否存在但进程活着不代表服务可用。我曾经遇到过Nginx进程还在但后端PHP-FPM已经僵死的情况页面全部超时可进程层面看一切正常。Monit可以通过设置端口探测例如定时访问HTTP接口既验证了80端口可达又可以检查返回内容是否包含预期文本这样就能发现“假活”状态并触发重启。1.3 什么时候该选Monit什么时候不该选总结我这两年多使用各种监控工具的经验Monit最适合下面这些场景个人VPS或家庭服务器配置一两台机器就可以覆盖所有服务小规模生产环境需要保证的几个关键服务能自动恢复不想引入复杂架构希望一个包安装完就能直接使用的场景团队刚起步运维人力有限需要低成本实现服务自愈如果机器规模已经上了几十台甚至上百台需要集中查看所有节点的状态、统一配置管理、做长期性能分析那Monit就有点勉强了。虽然它有个商业版的M/Monit可以做集中查看但效果和Prometheus这类专业监控方案还是有差距。建议这种情况下还是把主力监控放在Prometheus或者Zabbix上Monit只在每台机器上充当保活工具。2. 安装与基础配置从零到能跑起来2.1 安装前要认识的Monit目录结构Monit的安装非常简单Debian系的系统直接一条命令就能搞定sudo apt install monitCentOS系用yummacOS可以用brew安装过程基本没有坑。装完之后很多朋友会一脸懵因为找不到一个叫monit.conf的单一配置文件而是一堆目录和文件。我用了一段时间才把它的文件结构摸清楚这里给大家梳理一下/etc/monit/monitrc主配置文件监控规则的全局设置都在这里/etc/monit/conf.d/存放独立监控配置文件的目录一个服务一个文件方便管理/var/lib/monit/状态文件和事件队列存放目录Monit运行时会往这里写数据/var/log/monit.log运行日志排查问题时第一件事就是看这个文件主配置文件的路径在不同发行版上略有差异有的系统是/etc/monitrc有的是/etc/monit/monitrc可以通过monit -V命令查看编译时指定的路径。我习惯把所有自定义的监控规则都拆到/conf.d目录下每个服务维护一个独立的配置文件这样改完某个服务的规则不影响其他配置也方便做版本管理。2.2 最小可用配置从监控一个Nginx进程开始理解Monit配置的最好方式就是直接上手写一个最小配置。假设你的服务器上跑了一个Nginx希望实现“进程挂了自动重启”配置可以写成这样check process nginx with pidfile /var/run/nginx.pid start program /usr/sbin/nginx stop program /usr/sbin/nginx -s stop if cpu 80% for 3 cycles then alert if memory 300 MB for 5 cycles then alert if failed host 127.0.0.1 port 80 protocol http then restart这段配置怎么理解呢我用大白话解释一下每一行的含义check process nginx with pidfile指定了要监控的进程名和它的PID文件位置。Monit通过读取这个PID文件里的进程号来判断Nginx是否还活着如果PID文件不存在或者进程已经消失就判定为进程挂了。start program和stop program定义了Monit在需要重启或停止这个服务时要执行的命令。if cpu和if memory是资源阈值规则当CPU连续3个周期超过80%或者内存连续5个周期超过300MB时触发告警。if failed host 127.0.0.1 port 80 protocol http then restart是端口探测规则Monit会定时请求本机的80端口如果发现HTTP服务不可用就自动执行重启。写完之后先别急着直接启动用下面的命令做语法检查sudo monit -t如果输出Control file syntax OK说明配置没有语法问题。然后用sudo systemctl enable --now monit启动并设置开机自启。最后用sudo monit status查看当前各个服务的监控状态看到nginx这一项显示Running就说明监控已经生效了。2.3 Web管理界面与权限控制Monit还自带一个Web管理界面端口默认是2812。在浏览器里访问http://服务器IP:2812就能看到所有被监控服务的实时状态。不过刚开始用的时候我犯过一个错误直接把allow写的特别宽松导致公网可以访问这个管理页面非常危险。经过折腾后我总结出比较稳妥的配置方式set httpd port 2812 use address 127.0.0.1 allow 127.0.0.1 allow admin:monit这样配置之后Web界面只监听本机回环地址外部网络无法直接访问。需要远程查看时再通过ssh隧道把2812端口转发到本地访问既安全又省事。如果确实需要让某个内网网段访问可以改成allow 192.168.1.0/24的形式总之千万不要把管理端口直接暴露在公网。3. 核心规则拆解Monit配置语言的关键细节3.1 五种检查类型对应的场景与语法Monit的配置语言看起来简单但实际要写出生产级别的规则还是有一些细节需要注意。不同的监控对象对应不同的check类型我用表格给你列一下类型关键字检查内容示例进程检查check process进程是否存在check process redis with pidfile /var/run/redis-server.pid主机检查check host远程主机是否可达check host github with address github.com if failed port 443 then alert文件检查check file文件是否存在、大小是否变化check file syslog with path /var/log/syslog文件系统检查check filesystem挂载点、磁盘容量check filesystem rootfs with path /程序检查check program执行自定义脚本判断返回值check program backup with path /usr/local/bin/check_backup.sh系统检查check system整体系统负载、内存、CPUcheck system $HOST if loadavg (1min) 4 then alert每种类型适合不同的监控场景。比如check host有时候我会用来探测两台服务器之间的网络连通性配合告警一旦内网某条链路断了就能立刻收到通知。check file则适合监控日志文件是否在持续增长如果某个日志文件一直不变可能说明对应的服务已经停止写入这种“沉默预警”在排查问题时很管用。3.2 if...then...判断条件与动作的排列逻辑Monit的核心控制逻辑是if条件then动作看起来很简单但里面有几个关键点影响着规则能否正确触发。第一个关键点是条件的判定周期。Monit默认每隔30秒做一次检测但很多判断条件可以加for N cycles来抑制告警的频繁触发。例如if cpu 80% for 3 cycles意味着CPU占用率连续3个监控周期90秒都超过80%才会触发这能有效避免瞬时峰值引起的误报。第二个关键点是可以同时设置多个动作。Monit的动作包括alert发送告警、restart重启服务、stop停止服务和exec执行自定义命令。例如可以写成if memory 500 MB for 3 cycles then alert同时再加一行if memory 800 MB for 3 cycles then restart实现先告警、再升级处理。第三个关键点是规则之间的依赖关系。Monit在停止或重启一个服务时会考虑先处理依赖它的服务。比如应用服务依赖MySQL可以这样声明check process app with pidfile /var/run/app.pid depends on mysql check process mysql with pidfile /var/run/mysqld.pid start program /usr/sbin/service mysql start stop program /usr/sbin/service mysql stop这样当MySQL异常时Monit会先停止app再处理MySQL避免app在数据库还未启动完成时反复重启。3.3 告警通知配置邮件、短信与自定义脚本挂钩光有自动修复还不够很多时候也需要人工介入这时候告警通知就显得很重要。Monit默认支持邮件告警配置方式是在主配置文件里设置发件邮箱和收件人set mailserver smtp.example.com port 587 username monitexample.com password yourpassword with timeout 30 seconds set alert opsexample.com这里需要注意使用SMTP发送邮件一定要正确配置TLS协议。Monit对于不同SMTP服务商的TLS支持方式略有差异如果是Gmail这样的服务商还需要开启低安全性应用访问权限。如果是国内厂商的SMTP服务端口和认证方式要以服务商的文档为准。对于需要更强告警能力的场景Monit允许通过exec动作把告警事件推送到自定义脚本。例如if failed port 80 protocol http then exec /usr/local/bin/notify.sh这样可以把告警转发到钉钉、企业微信或者Slack实现类IM告警。我这边就是写了一个简单的Python脚本收到Monit传入的参数之后通过webhook推送到工作群效果非常直观。4. 一个完整落地案例从零配置Web服务加数据库监控4.1 场景设定与完整配置示例光讲语法容易让人感觉零散下面我分享一个真实的生产环境配置示例。场景是一台单机服务器运行Nginx和MySQL需求包括Nginx进程挂掉能自动重启MySQL进程挂掉能自动重启Nginx端口探测失败时发送告警磁盘使用率超90%时发送告警系统负载过高时发送告警MySQL的启动依赖Nginx避免野蛮重启按照需求我在/etc/monit/conf.d/目录下创建了两个配置文件。第一个文件专门监控Nginxcheck process nginx with pidfile /var/run/nginx.pid start program /usr/sbin/nginx stop program /usr/sbin/nginx -s stop if failed host 127.0.0.1 port 80 protocol http then restart if cpu 80% for 3 cycles then alert if memory 400 MB for 5 cycles then alert group web第二部分是监控MySQL和磁盘系统资源check process mysql with pidfile /var/run/mysqld/mysqld.pid start program /usr/sbin/service mysql start stop program /usr/sbin/service mysql stop if failed unixsocket /var/run/mysqld/mysqld.sock then restart if cpu 200% for 5 cycles then alert group database depends on nginx check filesystem rootfs with path / if space usage 90% then alert if inode usage 90% then alert check system $HOST if loadavg (1min) 4 then alert if memory usage 85% for 3 cycles then alert这里有几个细节值得说明。第一MySQL的PID文件路径在每个发行版上不一样在Debian系一般是/var/run/mysqld/mysqld.pid在CentOS系可能是/var/lib/mysql/mysql.pid配置之前一定要先确认实际路径。第二MySQL不像Nginx那样直接检测80端口我通过unixsocket检测本地socket文件是否能连接这样即使网络层异常也能准确反映MySQL的运行状态。第三depends on nginx表示MySQL的启停依赖Nginx避免在Nginx还跑着的情况下直接操作数据库导致的连锁问题。4.2 配置验证与常见报错处理配置写完之后通过monit -t做语法检查。如果输出Syntax OK就可以执行sudo monit reload让新的配置生效。这里要特别提醒一下改完配置后不要用systemctl restart monit那会把监控进程本身也重启一遍。应该用monit reload它会在不打断现有监控任务的情况下重新加载配置文件。接着用sudo monit summary查看整体监控状态预期会看到类似下面的输出Monit 5.25.2 uptime 3h 25m ───────────────────────────────────────────────── Service Name Status ───────────────────────────────────────────────── System Running Nginx Running MySQL Running rootfs Running如果某个服务显示Not monitored说明该服务的PID文件路径可能不对需要检查对应的PID文件是否存在。显示Initializing则说明Monit正在等待第一次检测完成通常等一个检测周期就会变成Running。4.3 实战测试手动杀掉进程验证自动恢复配置生效之后光看状态还不够最好手动做一次故障演练。我在部署完成后做过一次测试流程是这样的# 手动杀掉nginx进程模拟服务崩溃 sudo pkill nginx # 等30秒到60秒让Monit完成检测 sleep 60 # 检查nginx是否被自动拉起来 sudo monit status nginx ps aux | grep nginx | grep -v grep我在实操中遇到过一个有意思的情况pkill nginx之后Monit确实检测到了进程消失但nginx并没有在预期时间内恢复。后来排查日志才发现Monit执行start program时启动命令写成了/usr/sbin/nginx -t这个命令只是测试配置语法并不会真正启动服务。把启动命令改为/usr/sbin/nginx之后自动恢复就正常了。这个坑提醒我检查start命令是否真的能把服务拉起来而不是仅仅执行了一个校验类命令。5. 常见问题与排查技巧实录5.1 第一手排障思路与日志使用心得Monit出了问题第一件事不是去乱改配置而是看日志。运行日志默认在/var/log/monit.log里面会记录每一次检测的行为结果和误判原因。通过sudo tail -f /var/log/monit.log可以实时观察当某个规则触发时日志里会打印对应的判断过程非常直观。除了看日志还可以用monit -v参数做调试。这个参数会输出所有检测细节包括每个条件的计算过程和最终决策。遇到复杂的告警误报时我会先用这个模式跑一段时间结合日志找出规则里的问题。另外一个实用技巧是手动执行Monit脚本时一定要看清楚输出的措辞。monit status和monit summary的输出含义有区别前者显示每个监控项的详细信息后者是精简的汇总表。刚开始用的时候我把summary当成status看结果漏看了下面重要的提示信息多费了不少功夫。5.2 高频问题排查速查表我整理了一些自己踩过的坑和同事遇到的高频问题做成速查表供大家参考现象可能原因解决方案服务一直显示Not monitoredPID文件路径不正确或进程不以root权限运行确认PID文件实际路径修改配置中的pidfile值自动重启不生效start命令存在语法问题或命令执行权限不足手动执行start命令验证检查配置中的权限和路径告警邮件收不到SMTP配置错误或未通过TLS握手使用swaks等工具测试SMTP连通性确认端口和认证信息配置修改后不生效修改了配置文件但没有reload执行monit reload不要用restartCPU阈值误报频繁周期设置太短出现瞬时峰值增加for N cycles条件拉长判定窗口磁盘检查一直OKfilesystem的path配置错误用df -h确认挂载点路径修改配置Monit进程被OOM killMonit自身占用的资源未纳入管理给Monit加内存限制或用systemd配置OOMScoreAdjust5.3 监控周期与告警风暴的避坑告警风暴是刚用Monit时很容易遇到的一个问题。我一开始图省事把set daemon周期设成了5秒结果某个服务出问题时告警邮件像洪水一样涌来邮件列表直接被塞爆。后来学乖了把检测周期调成30秒同时给所有条件加了for N cycles的判定这样即使服务短时间抖动也不会产生大量重复告警。另外要特别注意Monit自身的资源占用。由于Monit默认以root权限运行如果它本身被系统判断为占用过高系统可能会优先杀掉它导致所有监控功能失效。我在部署重要服务的机器上会把Monit的CPU优先级调高一些同时用systemd服务文件里的OOMScoreAdjust参数给Monit一个比较高的分数确保内存紧张时Monit不会被最先杀掉。5.4 配置管理的小技巧最后分享一个关于配置管理的小习惯。Monit支持把多个配置文件放在conf.d目录下但这个目录默认只能由root用户写入。为了方便版本管理我会在Git仓库里维护一份配置模板通过Ansible或者一段简单的同步脚本分发到各台机器上。这样不管是调整阈值还是增加新的监控服务都可以通过Git记录每一次变更出问题的时候还可以回滚到历史版本排查效率高了不少。配置文件的命名也建议统一规范比如nginx.conf、mysql.conf、system.conf这样一目了然。当机器数量增加到一定程度你会发现这种清晰的目录结构能省掉很多排障时间。用Monit这几年我最大的感受就是它真正把“监控”和“处理”结合在了一起。以前用其他工具告警发出来了还要手动登录服务器操作现在大多数场景下Monit已经帮我自动处理完了邮件里看到的往往是“服务已自动恢复”的通知而不是半夜三点还爬起来重启进程。如果你也在寻找一种简单高效的服务器监控方案不妨从配置一个最小的Nginx监控开始试试相信你很快就能体会到这种省心的感觉。
返回列表