尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

网站7x24小时监控实战:从半夜宕机到安心睡觉

网站7x24小时监控实战:从半夜宕机到安心睡觉 凌晨3点47分手机在床头柜上连续震动屏幕亮起的那一刻我就知道又出事了。用户群里的截图一张接一张网站打不开了你们是不是跑了。爬起来开电脑、查DNS、看Nginx日志、翻数据库状态折腾到快五点才恢复躺回床上已经毫无睡意。这样的夜晚三年前我每个月都要经历几次。直到我下决心把自己的所有网站纳入一套7x24小时的监控体系这个噩梦才算真正结束。今天不聊虚的把我这两年多踩坑、迭代出来的完整方案分享出来包括监控指标怎么定、方案怎么选、通知怎么配、踩过哪些坑全部是可落地的实操。1. 半夜宕机的真实代价为什么睡个好觉必须靠监控1.1 宕机不只是损失订单还有你看不见的隐性成本很多个人站长觉得网站又不是电商平台偶尔挂一两个小时有什么关系。这个想法我过去也有直到一次挂站让我想明白了。那天上午九点用户开始反馈打不开我十点多才看到处理到中午。表面上看我在那段时间没有任何直接经济收入损失——网站主要靠广告和内容流量。但那一周搜索引擎统计里的收录和排名明显往下掉自然搜索流量少了三成恢复后将近一个月才慢慢爬回来。搜索引擎对不稳定站点的惩罚比大家想象中要重得多。如果是电商类或SaaS类站点损失就更直接了每一分钟不可用都意味着订单流失、客户满意度下降、续费率降低。业内有个粗略说法企业级站点每宕机一小时综合损失可能达到上千到上万元——这还没算客服沟通成本和品牌信任损耗。更重要的是半夜宕机如果没人发现到早上已经挂了四五个小时用户早就忍无可忍截图都发到行业群里了处理完还得挨个道歉。1.2 人工盯站是伪命题三个死穴谁也绕不过人不是7x24小时在线的。半夜两点你大概率在睡觉而用户发现宕机的时间不一定是你方便处理的时间。人工巡检是抽样不是全量。就算你每小时看一次监控面板两次巡检之间出了问题你依然要等最多60分钟才能发现。而这个时间已经足够搜索引擎抓取到错误页面用户也已经流失了。从发现到处理的链路太长。半夜爬起来开电脑、走流程、登录服务器、翻日志每一步都要几分钟到十几分钟。等你确认完用户早就从不耐烦变成愤怒了。所以真正的解法不是更勤快而是让系统在第一时间自动发现问题并且把定位信息一起塞到你的手机里。1.3 不同站点对宕机的容忍度完全不同在搭监控之前先给自己的网站分个级因为不同级别的监控策略完全不一样站点类型可容忍停机时间主要影响监控最低要求个人博客/内容站1小时以上SEO、阅读体验10分钟级探测企业官网10-15分钟客户流失、品牌形象5分钟级探测电商/交易平台1-2分钟直接订单损失30秒级探测多路告警开放API/业务基础设施30秒以内上游全部中断秒级探测电话/短信告警我把自己的站点分成了核心业务官网引流内容博客三个等级核心业务用30秒间隔监控官网用1分钟博客用5分钟。别小看这个分级它能直接决定你的监控成本和半夜被吵醒的频率。2. 盯站到底要盯什么可用性之外的四类核心指标2.1 可用性判断网站死没死的最小集合最基础的监控就是探测HTTP状态给目标URL发一个请求看返回码。正常情况下探针期望拿到200或者301/302跳转也可以接受一旦连续几次拿到5xx、网络超时或者TCP握手失败就判定为DOWN。这里有个细节如果只监控首页很可能漏掉深层页面的故障。更合理的做法是额外监控一两个真实的业务访问路径比如购物车接口或者登录API。我一般会专门写一个/healthz端点返回状态码和简单的依赖检查结果数据库连接、缓存连接探针直接打这个端点比打首页更能反映真实可用性。2.2 响应时间慢比挂更隐蔽也更容易被忽略网站返回200不代表用户访问顺滑。如果响应时间从200ms劣化到8秒可用性监控完全不会告警但用户体验已经崩塌了。这类缓慢故障最坑的地方在于服务器日志里全是正常请求状态码全是200你很难第一时间想到是性能问题。所以响应时间、TTFB、DNS解析时间这些指标也应该被纳入监控范围。一旦连续几次超过阈值比如核心页面超过3秒就触发预警让你在性能劣化成崩溃之前介入。2.3 SSL证书有效期最容易被忽略的高频故障我身边不少朋友遇到过证书过期导致站点半夜不可用这类故障往往发生在凌晨——因为用户分布在不同时区总有人在睡觉时间访问。很多证书都是90天自动续期看起来配置了自动化实际上续期任务早就失效了只是没人发现。应对办法很简单监控系统里加一条证书剩余天数的检查。剩余天数低于30天提醒一次低于7天再强制提醒一次。大部分工具都支持这类监控后面我会讲具体怎么配。2.4 内容完整性防止假活和篡改判断一个网站活着不能只看状态码。有几种非常常见的假活场景应用启动失败但Web服务器还在返回错误页首页被替换成攻击页面但状态码依然200接口返回200但响应体是空数组。这类问题用关键字匹配就能解决在探针配置里指定页面必须包含的某个文本比如注册登录某个产品名一旦响应体里找不到这些关键字就判定为异常。这个功能的成本极低但价值非常大强烈建议给每个核心页面都配上。2.5 主机与数据库解释为什么挂的内部视角前面说的都是黑盒监控从外部视角看网站挂了。但外部监控只能告诉你挂了不能告诉你为什么挂。这时候就需要白盒监控CPU、内存、磁盘、数据库连接数、慢查询、PHP-FPM进程数这些内部指标。工具方面也很成熟Zabbix有现成的MySQL模板Prometheus生态里有mysqld_exporter一条命令就能把数据库指标拉进时序库。磁盘写满、连接数打满、慢查询堆积这些根因往往要等到外部监控告警之后你再登录服务器才能看到。如果你提前把白盒监控配好告警消息里就能直接带着指标数据处理时间至少缩短一半。3. 方案选型托管SaaS、开源套件与自研脚本怎么选3.1 先丢结论三类方案的核心差别方案部署难度维护成本监控维度告警能力适合规模托管SaaSUptimeRobot等几乎为零零维护可用性、证书、关键字邮件/IM/短信小规模、快速上线自托管开源套件Uptime Kuma、Gatus低低可用性、证书、关键字、状态页各种Webhook/IM中小规模、个人/团队重型平台PrometheusAlertmanager、Zabbix、Nightingale较高中高可用性、性能、自定义指标、白盒高级路由、分组、静默大规模、复杂业务我现在的整体架构是Uptime Kuma做外部探活和证书监控UptimeRobot免费额度做第二路备份探测Prometheus blackbox_exporter做性能趋势和告警规则Zabbix再盯MySQL和内部主机。这套组合不是一次性搭起来的而是一个月一个月慢慢补全的。3.2 为什么我不建议只靠云厂商自带监控云厂商的控制台里也有云监控功能可以看CPU、内存、带宽也能设告警。但它有一个先天局限它只能看到云资源内部的指标模拟不了真实用户的访问路径。域名解析出问题、CDN边缘节点故障、第三方接口挂掉、服务器活着但Nginx进程假死——这些情况云监控统统无能为力。另一个容易被忽略的点是监控不能被监控对象绑架。如果告警系统本身运行在出故障的机器上或者依赖出故障的同一个域名邮件服务那故障发生的时候你会同时失去监控和通知。所以我的原则是探针永远部署在独立的机器上且机房位置尽量和业务服务器不在同一区域。3.3 自建还是托管我实际用下来的判断方法如果你只有1-3个站点或者本身没有一台可以常驻运行的服务器直接用托管SaaS就够了免费额度一般能覆盖几十个监控器对绝大多数个人站长完全够用。代价是探测间隔通常为5分钟免费层级无法做到秒级。如果你有服务器、网站数量超过5个或者想要可定制的状态页和告警规则强烈建议自托管一套Uptime Kuma。它采用Docker部署一台1核1G的小机器就能跑得很稳界面是中文的支持HTTP、TCP、Ping、DNS、证书、游戏服务器等几十种监控类型通知渠道覆盖了主流IM和Webhook而且自带公开状态页。如果网站数量上了量或者有数据库、中间件、K8s集群这类复杂基础设施要盯就得引入Prometheus Grafana Alertmanager这套可观测性组合。它做的事情和Uptime Kuma不太一样Uptime Kuma负责用户视角的在线状态Prometheus负责可量化的性能指标和预测性告警。Zabbix和夜莺Nightingale则在多元化监控和团队协作场景下更有优势。如果主要担心网络链路本身的质量还可以加一个SmokePing专门看丢包和延迟曲线。我的建议是不要一上来就追求大而全先用简单的把流程跑通再逐步加深。4. 通知配置是监控的命门半夜出事如何精准叫醒你4.1 通知渠道选型不是所有告警都值得半夜吵醒你监控发现异常之后最后决定损失多大的其实是通知这一环。如果通知没送达或者送达了你没看到前面部署全白搭。我见过太多人配置了监控结果只绑了一个邮箱邮件被过滤到垃圾箱里宕机通知第二天早上才看到——这等于没配。渠道到达延迟打扰程度费用适合场景邮件分钟级低免费恢复通知、日报、非紧急告警企业微信/钉钉/飞书群机器人秒级中免费默认告警通道Server酱/息知等推送服务秒级中免费/低价推送到微信/App短信云厂商短信服务秒级高按条计费核心业务P0告警语音电话秒级极高按分钟计费核心业务无人值守时段我的配置习惯是日常告警进企业微信群通过Webhook机器人接收P0级告警全站不可达、证书过期、数据库崩溃走短信恢复通知走邮件。这样既不会被告警轰炸搞到麻木又不会错过真正致命的问题。4.2 告警分级与静默窗口把人从告警疲劳里救出来告警疲劳是真实存在的。如果你把每次瞬时抖动、每次磁盘占用95%都当成大事短信每小时发一条人很快就会对所有通知麻木最后真正的大故障反而被忽略。我建议按严重程度分三级P0立即处理所有站点不可达、证书已过期、数据库不可用 → 短信/语音P1尽快处理单个核心站点不可达、响应时间连续超标 → 企业微信/钉钉P2关注即可证书剩余天数低于30天、磁盘占用超70%、CPU持续高负载 → 邮件/日报另外晚上22点到早上8点之间我会把P2级告警全部静默P0/P1照常发送。这样既保证了核心问题不被埋没又避免了半夜被磁盘80%这种不痛不痒的提醒吵醒。4.3 如何避免告警风暴重试确认和聚合是基本功告警风暴的来源很多探针所在网络抖动导致的瞬时超时、目标站点的CDN机房整体故障导致某个区域全部告警、服务器重启期间连续探测失败。如果每个探测周期都发一条告警十分钟就能把整个群刷屏。正确的做法是两条一是配置重试次数。我通常设置连续2次失败才进入DOWN状态瞬时抖动会被自动过滤。二是配置告警聚合。同一个组的监控项在短时间内只发一条汇总告警Uptime Kuma和Alertmanager都支持类似机制一定要用起来。4.4 告警自愈的边界先保证可用再谈根治有些朋友会进一步写Webhook联动脚本收到特定告警后自动重启Docker容器或者重启服务。这是很自然的想法也确实能在很多场景下止血。但我的经验是自愈只适合处理无状态且能快速安全重启的服务绝对不要套用在数据库、支付、订单这类有状态核心服务上。重启有时候会让软件恢复但也可能把未落盘的数据更新弄丢反而让问题更严重。自愈的目标是争取恢复时间不是替代根因分析。5. 落地部署用Uptime Kuma把全部网站纳入监控5.1 前置条件一台独立的低配云服务器Uptime Kuma对硬件的要求非常低一台1核1G、20G硬盘的云服务器就绰绰有余了。唯一要强调的是独立两个字——不要把它部署在你要监控的同一台机器上否则那台机器挂掉的时候监控也会跟着挂。机房位置最好和你的业务服务器拉开距离这样也能顺带发现网络链路的区域性故障。5.2 用Docker Compose快速部署先确保服务器装了Docker和Docker Compose插件。建立目录并写入compose文件services: uptime-kuma: image: louislam/uptime-kuma:latest container_name: uptime-kuma volumes: - ./uptime-kuma-data:/app/data ports: - 3001:3001 restart: always environment: - TZAsia/Shanghai说明几点/app/data是数据目录必须做卷映射否则容器重建后所有配置全丢TZ时区一定要设置否则告警消息里的时间戳会是UTC时区半夜醒了半天对不上号3001端口是默认Web端口如果机器有防火墙记得放行。启动命令就一行docker compose up -d浏览器访问http://服务器IP:3001就能看到设置页创建管理员账号后进入主界面。5.3 添加第一个监控器配置细节与参数含义进入主界面后点击添加监控器类型选HTTP(s)然后按下面的方式填URL填完整地址比如https://example.com/。如果你有健康检查端点填/healthz更合理。监控间隔核心站点选30秒普通站点60秒博客类可以放宽到180秒。超时设置一般默认5秒就行。如果目标站点本身响应就要4秒多阈值就要相应放大否则会频繁误报。触发告警的重试次数我会设置1-2次。关键字如果要防假活在关键字里填页面必须出现的文本还可以指定是包含还是不包含。状态页分组建议一开始就按业务模块分好组后面批量纳管时效率会高很多。保存之后系统就会按照你设定的间隔开始探测。主界面能看到每个监控项目的响应时长、证书剩余天数、历史可用率非常直观。5.4 公共状态页让用户自己看比挨个回复省心Uptime Kuma还有一个很实用的功能公开状态页。设置好之后会生成一个公开链接用户打开就能看到所有监控项的历史在线状态、当前是否有告警、过去90天的可用率。我的做法是在官网底部放一个系统状态入口指向这个状态页。以前遇到用户来问是不是服务器出问题了直接甩链接让他自己看真出故障时也不用挨个在群里解释状态页上的红点就是最好的公告。状态页支持自定义样式、分组和标题完全不输给商业服务。5.5 用Prometheus和blackbox_exporter补上性能视角Uptime Kuma擅长的是在线状态但对于响应时间的历史趋势和深度的告警规则它的能力相对有限。所以我还会在同一台服务器上跑一套轻量的Prometheus blackbox_exporter专门抓取HTTP探测指标再用Grafana展示。blackbox_exporter的配置写在blackbox.yml里modules: http_2xx: prober: http timeout: 5s http: preferred_ip_protocol: ip4Prometheus的抓取配置里通过relabel_configs把要探测的URL传给blackbox_exporter的参数scrape_configs: - job_name: web_blackbox metrics_path: /probe params: module: [http_2xx] static_configs: - targets: - https://your-site1.com - https://your-site2.com relabel_configs: - source_labels: [__address__] target_label: __param_target - source_labels: [__param_target] target_label: instance - target_label: __address__ replacement: 127.0.0.1:9115对应Grafana里就能看到几个关键指标probe_success探测是否成功、probe_http_duration_secondsHTTP请求耗时分位数、probe_ssl_earliest_cert_expiry证书剩余时间。告警规则可以这样写groups: - name: blackbox_alerts rules: - alert: SiteDown expr: probe_success 0 for: 2m labels: severity: p1 annotations: summary: {{ $labels.instance }} 连续2分钟不可达 - alert: CertExpiringSoon expr: probe_ssl_earliest_cert_expiry - time() 7 * 24 * 3600 labels: severity: p2 annotations: summary: {{ $labels.instance }} 证书将在7天内过期这套组合的好处是Uptime Kuma负责第一时间发现宕机并通知人Prometheus负责长期趋势分析和更灵活的告警规则两者各司其职互不冲突。6. 上线之后踩过的坑误报治理、监控自身故障与真宕机处理链路6.1 误报第一大来源探针IP被目标站点的防护策略误伤我的第一个教训来自WAF。网站前面挂了Web应用防火墙策略默认会拦截来自陌生IP的频繁请求。监控探针每30秒打一次很快就被识别成恶意扫描给封了IP结果是监控疯狂告警。排查了好久才发现不是网站挂了是探针被拉黑了。解决方式有两个一是把探针服务器的出口IP加入目标站点的白名单二是给探针请求加上可识别的User-Agent比如UptimeKuma/1.0 (monitoring)并在WAF里放行这个UA。如果目标站点用了CDN还要确认CDN节点不会对你的探针做限流。6.2 探针所在地网络抖动多路交叉验证才是正道某个晚上Uptime Kuma突然告警全部站点不可达我吓得连滚带爬起来一看服务器一切正常再查发现是探针所在的机器上游网络半夜在做割接导致出了几个小时的丢包。只部署一套探针就是会有这种监控先于业务出问题的情况。我的对策是部署第二路探测把关键站点在托管SaaS上再挂一遍免费额度足够覆盖核心网站。当两套监控同时判定DOWN才认定为真宕机只有一路异常时按误报处理。你也可以用两台不同位置的服务器各自部署Uptime Kuma再互相交换状态成本会高一些。6.3 告警通道的静默失效最隐蔽也最致命邮件告警最常见的问题是进垃圾箱这个前面说过。IM机器人告警的坑则是企业微信、钉钉的Webhook地址有可能失效如果机器人被移除或者token过期你完全感知不到监控还一直显示通知成功实际上什么都没推出去。我的习惯是每个周五下午固定发一条测试消息到所有告警通道确认链路是通的。别嫌麻烦我真的出过监控显示已发送、实际上群里已经两周没人说话的事故。测试消息成本非常低但能发现一大批隐藏问题。6.4 黑盒监控的盲区CDN缓存掩盖了源站故障有一个站点同时开了CDN某次源站挂了但CDN边缘节点上的静态页面缓存还在外部探针打到CDN节点时一切正常状态码200。所以哪怕监控显示UP真实用户打开首页也还能看但登录、下单这些动态接口实际已经全部报错。这种情况靠什么兜底一是监控里额外加入动态接口或API的探测地址二是在源站单独暴露一个/healthz健康检查端点探针直接打源站的真实IP绕开CDN三是配合业务日志做白盒告警一旦服务端错误率上升就通知人。充分理解用户看到的和源站实际的之间的差异才能避免这种盲区。6.5 半夜接到告警后的排查链路排查讲究顺序。接到告警后我会按下面的链路走基本不会浪费时间先看告警内容是单个站点还是全部站点。单个站点问题通常是应用层全部站点问题大概率是机器、网络、DNS或防火墙。SSH登录服务器先跑uptime和free -h一眼看负载和内存排除资源耗尽。docker ps看所有容器状态有没有退出或重启中的。用docker logs --tail 200 容器名看最近200行日志遇到明显的报错就直接定位。检查Nginx/Apache的错误日志确认是否有大量5xx。如果用了MySQL看连接数SHOW STATUS LIKE Threads_connected;和慢查询日志。处理完毕后确认监控恢复再把问题记到自己的运维笔记里做简单的根因复盘。大多数半夜故障最后都集中在内存泄漏导致OOM、磁盘写满、证书过期、数据库连接数打满这四类。把这四样作为白盒监控的重点提前配置好阈值能拦截掉80%的夜间事故。6.6 别忘了监控自身也要被监控最后一件容易被忽略的事Uptime Kuma本身也可能挂。容器被Docker自动更新搞崩、磁盘写满导致它写不了数据、服务器卡死……这些都是真实发生过的。如果你只依赖这一套监控监控挂了就等于整个体系瞎了。我现在会在另外一台完全独立的机器上用cron定时任务每分钟curl一次Uptime Kuma的状态页地址连续失败几次就通过备用渠道发告警。简单有效相当于给监控本身也上了一道保险。从被半夜宕机支配到两年多睡个好觉最核心的变化不是工具变多了而是整个监控逻辑从发现问题靠人巡检变成了发现问题靠系统、处理问题靠链路。Uptime Kuma负责探活Prometheus负责趋势Zabbix盯数据库和主机通知分级加多路备份最后再给监控自己加上自检——这套组合跑下来夜里被吵醒的次数反而越来越少了。如果现在的你还没有给网站装上监控今天就可以从一台小服务器和一套Uptime Kuma开始先把第一层探活跑起来再逐步补上性能和证书监控。真等下一次半夜宕机发生的时候你会感谢现在就开始动手的自己。
返回列表