一、装个探活脚本不等于做了监控

在服务器上写一个定时任务,每五分钟 curl 一下自己的首页,失败就发一条消息出去,这是绝大多数人做VPS监控的第一步。这个做法有一个致命缺陷:脚本和被监控的对象在同一个故障域里。机器宕机了,脚本跟着一起没了,告警永远不会发出来;磁盘写满了,脚本写不进日志,告警同样出不来;证书过期导致 Nginx 起不来,脚本依赖的运行环境可能也一起挂了。
延伸对照:cloudcone 的公开机型与线路说明,可结合本节的判断标准自行核对。
监控要有效,必须分成两个独立部分:被监控端负责采集和上报状态,监控端负责判断和通知。判断和通知这一侧,绝对不能放在被监控的机器上。这条原则听起来像废话,但它是区分「有监控」和「监控有用」的分水岭。
第二个常见误区是只监控进程存活。进程在不代表服务可用:Nginx 进程活着但上游 PHP 挂死,用户访问到的是 502;数据库进程活着但磁盘满导致写入全部失败,业务是坏的但探活返回成功;证书还有三天过期,页面今天还能开,但一天后就全站 HTTPS 报错。
第三个误区是只监控不值班。告警发到一个没人看的群里,等于没有监控。监控体系里,告警必须指向一个明确的、有响应能力的人,并且要规定多久没人处理算作故障升级。
那么VPS监控到底该测什么?可以从四个维度来分。第一类是可用性,也就是从外部访问某个真实业务地址能不能拿到预期结果。第二类是资源水位,包括 CPU、内存、磁盘空间、inode、连接数和文件句柄。第三类是安全与证书,包括 HTTPS 证书剩余有效期、域名与备案状态、SSH 登录失败次数。第四类是业务指标,包括关键接口的成功率、队列积压、备份任务的最后成功时间。这四类里,可用性和证书到期是最容易配、收益也最高的两类。
这四类之间不是并列关系,而是有明确的优先级。资源水位属于「预警」类指标,它告诉你趋势不好,但通常不会立刻造成故障;可用性属于「故障」类指标,它亮起的时候用户已经受影响;证书到期属于「定时炸弹」类指标,爆炸时间完全可预测,因此只要提前设好告警就等于消灭了这一类故障。所以一个刚起步的监控体系,优先级应该是可用性和证书到期先上,资源水位次之,业务指标最后。
还有一个心态上的问题需要说清楚。监控不是装完就一劳永逸的工具,它更像是给机器装上的一双眼睛,需要持续校准。阈值会随着业务变化而失效,采集项会因为软件升级而改名字,告警会因为组织调整而发到没人看的群里。这些都需要有人定期回看,否则监控会在某个时刻悄悄退化成一个只显示绿灯的摆设。
二、四类必监控指标与它们各自的阈值

指标选得太多是监控失效的常见原因。一个小团队同时盯三十个指标,最后的结果是所有人都不看。这里给出一套最小可用指标集,加上各自的判断阈值和超限后的典型含义。
延伸对照:digitalocean 的公开机型与线路说明,可结合本节的判断标准自行核对。
| 指标 | 采集方式 | 告警阈值 | 超限通常意味着 |
|---|---|---|---|
| 外部可用性 | 多地 HTTP 探活 | 连续 3 次失败 | 宕机、端口被封、服务崩溃 |
| 证书剩余天数 | 握手读取证书 | 少于 21 天 | 无人续签,到期即全站 HTTPS 报错 |
| 磁盘使用率 | statvfs 或 df | 超过 85% | 日志未轮转、备份文件堆积 |
| inode 使用率 | df -i | 超过 80% | 大量小文件,删了数据也释放不了 |
| 内存可用比例 | free 输出的 available | 低于 15% | 进程泄漏或缓存不足,OOM 前兆 |
| CPU 负载 | loadavg 除以核数 | 持续大于 1.5 | 任务排队,接口延迟上升 |
| 磁盘 IO 等待 | iostat 的 %util | 超过 80% | 磁盘瓶颈,读写变慢 |
| 备份最后成功时间 | 检查备份产物时间戳 | 超过 26 小时 | 备份任务静默失败 |
| SSH 失败登录次数 | journalctl 统计 | 5 分钟内超过 20 次 | 爆破尝试,需改端口或封禁 |
| 端口暴露变化 | nmap 对比基线 | 新增非预期端口 | 进程被入侵或误开端口 |
阈值不是拍脑袋定的,按这个思路校准:先连续采集一周正常流量的数据,取峰值作为基线,再把告警阈值设在基线的八成左右,同时保证有至少 20% 的余量给突发流量。CPU 负载这类的相对指标可以用「负载除以核数大于 1」作为通用起点,内存则更适合看可用绝对值而不是百分比,因为 Linux 会拿空闲内存做缓存,看百分比会天天误报。
内存告警最容易配错。free -m 里的 available 才是真正的可用内存,free 和 buff/cache 都不适合作为判据,因为缓存是随时可以回收的。误报的告警会很快让人养成忽略通知的习惯,这是告警系统失效最常见的方式。
磁盘水位这一项要区分三个不同的量。df -h 看的是数据块占用,df -i 看的是 inode 占用,也就是文件数量配额,du -sh 看的是某个目录的实际内容大小。三个量互相独立,删掉大文件可能只降低第一个,删掉大量小文件可能只降低第二个。有一个经典现象是磁盘明明显示还有几十G 空间却写不进去文件,报错是 No space left on device,但 df 看起来空间很足,这时候就要查 inode。
关于 inode 的判断经验是这样:如果你跑的是 WordPress 加大量上传图片、或者用面板装了一堆小站点,inode 消耗通常比空间消耗更早触顶。单个文件平均按 4KB 块计算,一个 10GB 的目录如果都是几 KB 的小文件,可能吃掉上百万个 inode,而很多虚拟机的文件系统 inode 上限只有几十万。
# 分别查看块占用与 inode 占用,找出真正的瓶颈
df -h / && df -i /
# 找出小文件最多的目录,inode 告警时定位用
find /var/www -type f -size -8k -printf '%h\n' 2>/dev/null | sort | uniq -c | sort -rn | head -10
三、外部探活:为什么不能放在自己的机器上

内部监控能发现「服务异常」,发现不了「机器整个没了」。外部探活是唯一能覆盖这个场景的手段,它的部署原则是:探活节点必须在另一台机器上,最好在不同机房、不同网络段,甚至不同服务商。
延伸对照:hostwinds 的公开机型与线路说明,可结合本节的判断标准自行核对。
探活的内容分两档。基础档是只测 TCP 端口能不能连上,能连上就认为机器活着,这能覆盖宕机、网络中断、防火墙误封端口这类问题,但对服务假死无能为力。进阶档是发一个真实的 HTTP 请求,检查返回的状态码、响应时间和响应内容里的特征串。
# 基础档:检查端口连通性与响应时间,用 -o /dev/null 只要状态码
curl -sS -o /dev/null -w "code=%{http_code} dns=%{time_namelookup}s ttfb=%{time_starttransfer}s total=%{time_total}s\n" \
--max-time 10 https://your-site.com/
# 进阶档:同时校验状态码与内容特征串,防止假页面返回 200
BODY=$(curl -sS --max-time 10 https://your-site.com/)
CODE=$(curl -sS -o /dev/null -w "%{http_code}" --max-time 10 https://your-site.com/)
if [ "$CODE" != "200" ]; then echo "FAIL status=$CODE"; exit 1; fi
if ! echo "$BODY" | grep -q "期望出现的特征串"; then echo "FAIL content mismatch"; exit 1; fi
echo "OK"
判读方式:进阶档的价值在于识别「200 但内容是错误页」这种情况。很多面板的错误页返回 200,内容却是「站点正在维护」或者一句数据库错误。只看状态码的监控会一直显示正常,而用户看到的是坏页面。
多个探活点比单个探活点重要得多。单点探活有两个无法排除的假故障:探活节点自身故障,以及探活节点到目标之间的某条链路故障。单点挂掉时你会收到一条「服务器宕机」的告警,而实际上是探活节点的问题,这类假故障会迅速消耗掉你对告警的信任。至少配三个探活节点,分处不同地区。
检测目标被墙或被运营商劫持也是探活的一个用途。在境内和境外各放一个探活点,如果境内通、境外不通,或者两边返回的内容不同,那就说明 DNS 解析被污染或流量被劫持了。
探活的频率选择也有讲究。一分钟一次是通用起点,能覆盖绝大多数业务中断;如果你的站点有明显的秒级峰值特征,比如秒杀、活动开抢,可以针对关键接口单独加一个 10 秒级的高频探活。但不要把所有接口都设成 10 秒级,成本和噪音都会上升。合理的做法是分层:核心入口 30 秒一次,普通页面 1 分钟一次,后台接口 5 分钟一次。
探活的历史数据比单次结果更有价值。单次成功只能说明现在活着,连续一周的成功率曲线能告诉你这台机器是不是在反复重启、是不是每天凌晨某个时间点必然不可用。后者往往是定时任务把磁盘或内存吃满造成的,用探活历史配合定时任务的时间点,很容易对上号。
# 把探活结果写成时序数据,用来看连续可用率而不是只看单点
while true; do
code=$(curl -sS -o /dev/null -w "%{http_code}" --max-time 10 https://your-site.com/ 2>/dev/null)
echo "$(date -Is) $code" >> /var/log/probe.log
sleep 30
done
四、告警噪音治理:一条不该看的告警比没有告警更糟

监控上线三个月后,告警系统通常会退化成一个每天几百条消息、没人点开的群。这个结果不是设计失败,而是没有主动治理噪音的必然结果。噪音的来源主要有四类。
延伸对照:interserver 的公开机型与线路说明,可结合本节的判断标准自行核对。
第一类是抖动型噪音。阈值设在临界值上,指标在阈值上下反复横跳,每小时触发几十次。解决办法是加持续时间条件,也就是连续 N 个采集周期超限才告警,或者设置滞回区间,比如用量超过 90% 告警、降到 80% 以下才算恢复。这一条能把大部分噪音消掉。
第二类是依赖型噪音。数据库抖动导致应用接口超时,应用超时触发上游调用失败告警,链路一层层放大,最后一个根因产生几十条消息。解决办法是依赖拓扑梳理,把告警按依赖关系分层,只有最下游的根因节点才直接找人,上游节点只做记录。
第三类是计划内噪音。定时任务在凌晨跑备份,磁盘写入高峰导致 IO 等待告警;每周日全站维护导致可用性告警。解决办法是维护窗口,在告警系统里登记计划时间段,窗口内的对应告警自动降级为通知。
第四类是无效指标噪音。指标本身有价值但没有任何对应的处置动作,这种告警应该直接关掉而不是留着。
# 典型的持续时间判定:连续 3 次超限才触发,恢复时留滞回
if [ "$(cat /sys/fs/cgroup/system.slice/systemd-journald.service/memory.current 2>/dev/null || echo 0)" -gt 0 ]; then
count=$(cat /run/mem_alert_count 2>/dev/null || echo 0)
count=$((count + 1))
echo "$count" > /run/mem_alert_count
[ "$count" -ge 3 ] && curl -sS -X POST "$WEBHOOK" -d '{"text":"内存连续3个周期超限"}'
else
echo 0 > /run/mem_alert_count # 恢复正常,计数清零
fi
判读方式:给告警系统做一次审计,把过去七天的告警按规则和触发次数排序。排在最前面的几条规则通常贡献了 80% 以上的消息量,逐条决定是加持续条件、加维护窗口、还是直接下线。上线一个月后再审计一次,噪音应当处于持续下降的趋势。
还有一个经验指标:一条告警如果连续被忽略三次以上,就应该被修改或关闭。人会忽略噪声,这是不需要争论的事实。
噪音治理要形成闭环,否则半年后又会回到原样。闭环的做法是每月做一次告警复盘,把上月的告警按规则统计出触发次数、确认次数、误报次数、平均响应时长,把这个表拿来做季度改进的输入。只关掉噪音而不统计,改进就没有依据。
告警分组也是降噪的有效手段。把同类告警合并成一条聚合通知,比如把「磁盘 85%」「磁盘 90%」「磁盘 95%」合并成一条带等级标记的通知,而不是三条分开发。这样既保留了信息量,又减少了消息条数。同时给每条通知加上机器名称、故障类型、影响范围三个标签,值班的人不用再点进详情才知道事情多严重。
还有一点:恢复通知同样重要。很多系统只发告警不发恢复,导致值班的人不敢关掉告警,因为不知道是不是真的好了。发一条「已恢复,恢复耗时 12 分钟」的确认消息,能让人放心地把告警关掉,同时也提供了故障时长的真实数据。
五、证书与域名到期:这类故障是完全可以提前避免的

HTTPS 证书到期是 VPS 运维里最常见也最荒谬的故障类型。它的特点是完全可预测,但每年都在重复发生。原因是证书的有效期动辄 90 天到一年,而续签往往依赖人工操作或者一个没人记得的定时任务。
延伸对照:itldc 的公开机型与线路说明,可结合本节的判断标准自行核对。
监控证书要监控三件事:到期时间、证书与域名是否匹配、以及自动续签是否真的在工作。第三条最容易被忽略——自动续签脚本写了不代表它在跑,可能因为 cron 环境变量缺失、webroot 路径不对、或者 DNS 提供商的 API 密钥过期而早已失效,但没人发现。
# 读取证书剩余天数,enddate 转成天数差
enddate=$(echo | openssl s_client -servername your-site.com -connect your-site.com:443 2>/dev/null \
| openssl x509 -noout -enddate | cut -d= -f2)
days=$(( ( $(date -d "$enddate" +%s) - $(date +%s) ) / 86400 ))
echo "证书剩余 $days 天"
[ "$days" -lt 21 ] && echo "WARN: 证书即将到期"
# 检查证书覆盖的域名是否包含你的实际域名
echo | openssl s_client -servername your-site.com -connect your-site.com:443 2>/dev/null \
| openssl x509 -noout -text | grep -A1 "Subject Alternative Name"
判读方式:把证书剩余天数设成阶梯告警而不是单一阈值。少于 45 天发一条提醒,让有充足时间处理;少于 21 天升级通知;少于 7 天变成紧急并直接联系值班人。阶梯式告警的好处是它给了人反应时间,而不是等到当天才发现。
自动续签的验证方式是主动检查续签后的文件时间戳,而不是等待它到期:
# 检查续签产物是否在最近一次周期内被更新
find /etc/letsencrypt/live -name "fullchain.pem" -mmin -1440 -print
# 手动触发一次续签并观察结果,dry-run 不会真的签发
certbot renew --dry-run 2>&1 | tail -20
# 检查 nginx 是否已加载新证书
openssl s_client -servername your-site.com -connect your-site.com:443 2>/dev/null \
| openssl x509 -noout -startdate
判读方式:certbot renew --dry-run 返回成功且输出里没有报错,才说明自动续签链路是通的。这条命令建议放进每日巡检。域名本身的到期提醒同理,很多用户只盯着服务器上的证书,忘了域名注册商的续费日期,这类故障恢复起来更麻烦,因为需要登录另一个平台。
还剩两类到期项值得单独提。一是付费插件和主题的授权密钥,比如某些商业主题按年授权,到期后站点能访问但主题功能被锁,这类问题同样需要进监控。二是备案与合规相关的到期项,如果站点放在国内机房,备案信息里的域名、主体信息需要保持有效,备案异常会导致访问被阻断或跳转。
证书到期还有一层间接影响容易被忽略:搜索引擎会因为大面积 HTTPS 错误判定站点不可用,权重和收录都会受影响。所以证书监控不只是可用性问题,也是流量问题,对做 SEO 的站点来说优先级应该更高。
六、磁盘增长与写满:最常见的宕机原因

统计上,VPS 最常见的宕机原因不是内存耗尽,而是磁盘写满。磁盘满的时候,Nginx 写不了日志会拒绝服务,MySQL 写不了 binlog 会崩溃,systemd 写不了 journal 会让很多服务无法重启。更麻烦的是,此时你可能连不上机器,因为 SSH 也要写日志。
延伸对照:iwebfusion 的公开机型与线路说明,可结合本节的判断标准自行核对。
根本原因通常是三类。第一类是日志没有轮转。应用的访问日志、错误日志、数据库慢查询日志、auditd 日志,全都在无限增长。第二类是容器镜像与构建缓存堆积。第三类是备份文件写在了本机,没做清理。
# 找出占用最大的目录和文件
sudo du -h --max-depth=2 /var 2>/dev/null | sort -hr | head -20
sudo find /var/log -type f -size +100M -exec ls -lh {} \;
# 检查 logrotate 是否真的在按配置轮转,而不是配了没生效
sudo logrotate -d /etc/logrotate.conf 2>&1 | grep -A3 "rotating pattern"
判读方式:看 logrotate 的调试输出里每个日志文件的 rotating pattern 频率是不是符合预期。如果配置文件里有条目但 daily 之类关键字写错,logrotate 不会报错,只会什么都不做。用 logrotate -d 而不是 -v,前者只模拟不执行,安全。
预防上分两层。软件层用 logrotate 配好轮转和保留份数;系统层加一条磁盘使用率超过 85% 的告警,并留出至少 20% 的应急空间,因为写满到爆之间往往没有足够时间处理。
# logrotate 配置示例:每天轮转,保留 14 份,压缩
/var/log/nginx/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}
还有一个容易忽略的动作是给容器加清理策略。Docker 长期运行会积累退出容器的日志和悬空镜像:
# 清理悬空镜像与无引用构建缓存,不影响正在运行的容器
docker image prune -f
docker builder prune -f --filter "until=168h"
# 限制单个容器的日志大小,防止它把磁盘写满
docker update --log-opt max-size=50m --log-opt max-file=3 <container>
磁盘增长还有一个数据层面的来源:数据库本身。MySQL 的 binlog、慢查询日志、undo log、临时表文件都会持续增长,其中 binlog 在开启了日志保留时间之后仍然可能因为大事务而堆积。清理的顺序是:先确认主从复制已经消费完对应的 binlog 文件,再用 PURGE BINARY LOGS 按时间点清理,绝对不要直接删文件。
# 查看当前 binlog 占用和保留设置
mysql -u root -p -e "SHOW BINARY LOGS;"
mysql -u root -p -e "SHOW VARIABLES LIKE 'expire_logs_seconds';"
# 确认复制状态后再按时间点清理,注意 TO 是保留到的位置
mysql -u root -p -e "PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 3 DAY);"
判读方式:SHOW BINARY LOGS 列出的文件总大小如果超过磁盘的十分之一,就该清理了。清理前一定要确认没有备用的复制节点还在读这些日志,否则复制会直接断掉。
七、监控本身也要被监控

监控系统的静默失败和被监控服务的失败一样危险。最常见的场景是探活脚本挂了或者告警通道本身出问题,服务器早就宕了,但监控一直显示正常,值班的人完全不知情。
延伸对照:racknerd 的公开机型与线路说明,可结合本节的判断标准自行核对。
防御思路是给监控链路设计一个「自检心跳」。监控端每五分钟往一个外部服务写一条心跳,如果超过十五分钟没有收到心跳,外部服务就发出告警。这相当于给监控装了一个不在监控体系内的看门狗。
# 监控端定时写心跳到外部服务,外部服务在超时后告警
echo "$(date -Is) beat" | curl -sS -m 10 -X POST \
-d @- "https://hc-ping.com/你的UUID" > /dev/null
# 检查本地监控进程是否还在
systemctl is-active node_exporter || echo "exporter 已停止"
systemctl is-active nginx || echo "nginx 已停止"
判读方式:自检心跳必须写到监控体系之外的第三方服务,用自己体系的组件做自检等于自己给自己签字。这里需要注意,如果告警通道本身就是故障点,那这条自检也要走另一条通道,比如手机短信或者另一个即时通讯工具。
告警通道本身也要做冗余。常见做法是:即时通讯通道负责日常,邮件通道负责留档与兜底,电话或短信只在紧急级别触发。通道越多越好不现实,但至少要有两条互不依赖的路径——如果两条都走同一个 webhook 或同一台服务器,等于只有一条。
还有一个做法是定期做告警演练。人为触发一次测试告警,确认它真的能到达值班的手机。这一步花不了五分钟,但能避免事故当天发现告警通道根本没通的情况。
监控端自身的资源也要监控。很多监控系统把自己的磁盘和内存用光,采集端反而没事。给监控端也加一组同样的告警规则,尤其是磁盘使用率,因为采集的历史数据会持续占用空间。历史数据需要设保留期,到期自动删除,不然监控端会先于业务机出问题。
八、免费监控方案对比与选型

监控方案的选型无非三条路:完全自建、免费 SaaS 加自建采集、付费商业方案。对于个人站长和一两台 VPS 的小团队,免费加自建通常够用。
延伸对照:zenlayer 的公开机型与线路说明,可结合本节的判断标准自行核对。
自建最典型的组合是 Node Exporter 加 Prometheus 加 Grafana 加 Alertmanager。这套是完整的指标采集与可视化方案,但组件多、资源占用不小,1 核 1G 的小机器上跑起来比较吃力,通常需要用一台稍大的机器专门做监控,或者用 Docker 隔离运行。适合有运维能力、需要长期积累多台机器历史数据的人。
更轻量的自建组合是 Node Exporter 加一个简单的告警脚本,用 Webhook 发到即时通讯。这类方案没有历史数据存储能力,看不了过去一周的曲线,但配置快、占用小。
免费 SaaS 的优势是探活节点天然在外部,不需要你自己再部署一台机器做外部探活,也自带全球多节点探测和历史曲线。局限是采样精度通常在 1 分钟到 5 分钟,抓不住秒级的瞬时抖动;免费档往往有探测频率和监控数量限制;数据留存天数也有限。
| 方案类型 | 外部探活 | 历史曲线 | 资源占用 | 适合人群 |
|---|---|---|---|---|
| Node Exporter 加脚本加 Webhook | 需另找外部节点 | 需自己接存储 | 极低 | 单机个人站 |
| Prometheus 加 Grafana 加 Alertmanager | 需另找外部节点 | 强,可长期留存 | 中高 | 多机运维团队 |
| 免费 SaaS 探活 | 自带多地节点 | 有,留存天数有限 | 无本地开销 | 新手与轻量场景 |
| 商业付费监控 | 自带多地节点 | 强 | 无本地开销 | 有 SLA 要求的生产业务 |
在本站广告库里有结构化套餐数据的商家中,justg 公开的 RosCloud 系列可以作为自建监控节点的候选,因为监控场景主要消耗磁盘、带宽和流量,而不是 CPU。其公开套餐按月计价,入门款 2 核 1G、20GB 磁盘、500Mbps 端口、1TB 月流量为每月 19.99 美元,中档 3 核 2G、40GB 磁盘、2TB 流量为每月 29.99 美元,较高配置的 7 核 24G、320GB 磁盘、6TB 流量为每月 69.99 美元。其余在广告库中只有文字简介的商家,例如 CloudCone、DigitalOcean、Hostwinds、Interserver、ITLDC、iWebFusion、RackNerd、Zenlayer、SpinServers,具体机型与报价请以官网当日报价为准。这些数据用于说明选型时的资源口径,不代表推荐在监控节点上跑高负载。
选型时按这个顺序判断:先确定探测频率要求,再看是否需要外部探活和多节点,最后才看历史数据留存需求。绝大多数场景下,一分钟一次的外部探活加四条核心告警,就足以覆盖九成以上的实际故障。
不管选哪种方案,都要做一次上线前的验收测试。验收的方法是故意制造几种故障,看监控是不是都能正确报出来:手动停掉 Nginx 看可用性告警是否触发,往磁盘里塞满文件看空间告警是否触发,改掉系统时间看证书告警是否误判,停掉采集进程看监控端是否报告采集失败。四项都通过了,这套监控才算真的可用。
# 验收测试:停掉服务,确认外部探活能报出来
systemctl stop nginx && sleep 60 && systemctl start nginx
# 验收测试:制造磁盘接近满的状态,观察告警阈值
dd if=/dev/zero of=/var/tmp/fill bs=1M count=1024 2>/dev/null && df -h / && rm -f /var/tmp/fill
判读方式:故障注入后应该在阈值对应的时长内收到告警,恢复后应该收到恢复通知。两次通知之间的时间差就是探测间隔加上通知延迟,这个数字要记下来,它是判断监控是否够灵敏的依据。
九、值班流程:告警之后该做什么

监控系统只做检测,处置流程必须单独设计。没有流程的告警只会让人在半夜收到消息时先慌五分钟再开始想。
延伸对照:justg 的公开机型与线路说明,可结合本节的判断标准自行核对。
一个可用的最小流程分五步。第一步是确认,收到告警后先判断是探活节点自身故障还是目标真有问题,最快的办法是看第二、第三个探活节点的结果。第二步是定位,登上机器看是什么挂了,跑一遍 systemctl --failed、df -h、free -m、journalctl -p err -n 50 这四条命令基本能覆盖大部分场景。第三步是止损,网站打不开时先恢复可访问性,比如切到备用节点或者把证书换回有效版本,再排查根因。第四步是修复,处理完把告警标记为已解决并记录原因。第五步是复盘,把故障原因、发现时间、恢复时间写进复盘文档。
# 一次排障的四条基础命令,输出直接贴进工单
systemctl --failed --no-pager
df -hT && df -ih
free -m
journalctl -p err -n 50 --no-pager
# 看最近的重启记录,确认是不是反复崩溃重启
last -x reboot | head -10
判读方式:为每类告警预先写好处置卡片,放在随手能打开的地方。卡片上写清楚第一步该执行哪条命令、什么情况下该重启服务、什么情况下该联系商家、什么情况下该切换备用节点。没有卡片的告警,平均恢复时间会明显长于有卡片的场景,因为大量时间花在了回忆上。
在写清楚告警级别的定义。三级比较实用:紧急是核心业务不可用,需要立刻响应;重要是部分功能异常或资源接近阈值,需要当班处理;提示是仅供留档,可以次日看。每级对应不同的通知渠道和不同的升级时间,比如紧急级别 15 分钟无人响应就自动升级到电话通知。
恢复时间也该被度量。记录从告警触发到业务恢复的耗时,按月统计中位数,这个数字是评估监控系统价值的唯一客观依据。如果监控上线半年,这个中位数没有下降,那说明监控只是增加了工作量。
值班流程里还有一个容易被忽略的动作:交接。轮班或者值班人换人时,要把当前未解决的告警、正在进行的变更、已知的隐患清单交接过去。一份写在文档里的交接清单,比口头交代可靠得多。
最后是复盘的质量。复盘不是追责,而是要把每一次故障转化成一条具体的改进项,并且这条改进项要真的落到某个配置或某份文档上。衡量复盘是否有效的标准很直接:同一个根因导致的故障,第二次发生时是否还发生。如果三个月前的故障原因原样又出现了一次,说明上次的复盘没有落地。
十、常见问题

一台 1 核 1G 的小机器,装得下完整的监控系统吗? 完整套装比较勉强。1 核 1G 上跑 Prometheus 加 Grafana 加 Alertmanager 加 Node Exporter,加上被监控的业务本身,很容易触发 OOM。更实际的做法是用轻量方案:只装 Node Exporter,采集数据后把关键指标推给外部的免费 SaaS 告警平台,或者用 shell 脚本直接做阈值判断加 Webhook 通知。
监控探针本身会不会拖慢服务器? Node Exporter 的默认采集是拉取式的,只在被请求时读取系统指标,开销很低,正常情况下对业务的影响可以忽略。但要注意不要开启高频细粒度采集,也不要把探针暴露在公网不加认证。做一次基准对比:装探针前后各跑一轮压测,看响应时间的差异是否在可接受范围。
没有公网 IP 的机器怎么被外部探活? 用内网穿透或者在有公网 IP 的机器上装一个 Agent 主动上报心跳。上报模式对被监控端没有入站要求,比较适合内网机器和云厂商的私有子网实例,代价是上报节点自己挂了会连累被监控端显示为异常。
告警发到微信或者 QQ 群,为什么经常看不到? 常见原因有三个:webhook 机器人被移出了群、群消息被设置为免打扰、以及告警通道本身有频率限制被静默降级。验证方法是在群里手工发一条测试消息确认机器人还在,再检查 webhook 服务商的返回码是不是 200。
监控数据要保留多久? 日常告警依赖的是最近几分钟的数据,不需要长期留存;但趋势分析需要至少 30 天到 90 天的历史。免费 SaaS 通常给的是 7 天到 30 天,超出部分一般要付费。判断够不够用的方法是看你的容量规划周期,比如你要按季度评估是否该升配,那就至少要留够 90 天的磁盘和内存曲线。
监控会不会被挖矿程序或者入侵者关掉? 会,而且这正是只做内部监控的危险之处。入侵者拿到 root 后第一件事往往就是停掉监控和日志。防御手段有三层:监控端运行在另一台机器上;关键的探活由外部节点发起,被关掉后外部立刻报不可达;文件完整性和关键进程的异常退出由外部的完整性检查工具检测,而不是靠机器内部自己报告。
告警阈值应该设多少? 别用拍脑袋的整数,先连续采集一周的正常数据,取峰值的八成作为初始阈值,再观察两周的误报情况逐步调整。起步阶段宁可让阈值偏松一点,也不要一上线就每天几十条告警。一个刚建立起来的监控系统如果第一周就被拉黑,后面很难再让人愿意看它。
监控该监控几台机器,端口要不要开在公网? 监控端要覆盖所有在跑业务的关键机器,数量上没有上限但要有优先级,核心业务机优先。采集端口绝对不要裸露在公网,用 SSH 隧道、内网网络或者在前面加一层带认证的反向代理。
多个站点放在同一台 VPS 上,监控怎么组织? 按站点而不是按机器组织告警标签。同一台机器上跑了五个站,机器级告警只能告诉你「这台机器有问题」,站点级告警才能告诉你「哪个站挂了」。做法是每个站点配一条独立的 HTTP 探活加内容特征串校验,标签里带上站点名。
告警需要发到邮件吗,邮件会不会太慢? 邮件适合留档不适合紧急通知,邮件客户端的推送延迟可能到几分钟甚至更久,值班时人往往不会盯着邮箱。紧急级别走即时通讯或短信,邮件只作为兜底和历史归档。
服务器换 IP 或者迁移机房之后,监控要改哪些地方? 至少要改四处:探活目标地址、证书指纹基线、告警里的机器标识、以及 IP 段的基线比对。改完之后必须重新做一次故障注入验收,否则很可能出现「监控一直显示异常」或者「监控显示正常但其实没在监控新地址」这两种情况。
一年下来监控费用大概多少? 免费方案覆盖单机和十几台机器的日常需求是够的,零成本。规模上到几十台机器、需要长周期历史留存和更细的采样频率时,才需要转向付费。按单机每月几美元的常见口径估算,成本通常正比于被监控的机器数量与采样频率,与业务流量无关。
监控装好了还需要做安全加固吗? 需要,而且监控节点本身就是高价值攻击目标,因为它能看见所有被监控机器的地址、端口和运行状态。监控节点要做到最小化暴露:只开必要端口、只允许固定来源 IP 访问、用强口令或者密钥登录、关闭密码登录。监控节点被拿下,攻击者就能同时掌握你全部业务的资产清单。

喜欢
高兴
鬼脸
呵呵
无聊
伤心