云主机异常报警如何处理?
- 来源:纵横数据
- 作者:中横科技
- 时间:2026/5/6 15:46:33
- 类别:新闻资讯
半夜两点,手机突然像发了疯一样震动,一条接一条的报警短信涌进来。你迷迷糊糊地从床上爬起来,看到监控群里已经炸开了锅:CPU使用率飙升到98%,磁盘空间不足,HTTP响应码5xx数量暴增。这种场景,做过运维的朋友一定不陌生。说实话,这些年我手机里存得最多的截图就是半夜的报警记录,每个深夜惊醒的瞬间都让人记忆犹新。
但是,报警本身不是目的,处理报警才是真功夫。很多新手看到报警就慌了,第一反应是直接重启服务器,或者盲目地查一通日志却找不到头绪。其实,处理异常报警有一套成熟的思路和方法。今天我就把自己在无数次半夜被叫醒之后总结出来的经验,老老实实地分享出来。希望你看完之后,下次手机再响,能从容地给自己倒杯水,然后有条不紊地把问题解决掉。
接到报警之后的第一件事不是动手
我见过最糟糕的做法,就是一听见报警就立刻登录服务器,然后凭感觉一顿操作。正确的第一步,其实是先看报警的“内容”和“上下文”。现在的监控系统一般都会告诉你具体是什么指标超出了什么阈值,以及这个异常是什么时候开始的。这些信息比你冲动地执行任何命令都重要。
举一个例子,有一次凌晨四点,报警说某台数据库云主机的磁盘使用率达到了92%。我们的值班同事一看就慌了,马上登录服务器,发现是binlog把磁盘吃满了,他二话不说执行了purge操作,清理了几十GB的日志。但问题是,他没有先确认这个binlog是否还需要被从库拉取。果然,清理之后从库延迟瞬间飙升,因为主库已经把从库还没同步的日志给删了。最后花了两个小时重新搭建从库,损失惨重。如果他接到报警后,先看一眼从库的同步状态,查看哪些binlog还在被使用,再决定清理范围,这个事故完全可以避免。
所以,收到报警的第一件事是冷静下来,看清楚报警内容,然后花一两分钟思考:这个异常指标可能是什么原因导致的?会影响到哪些业务?我有没有应急预案?脑子里有了一个大致的判断,再开始动手。
CPU报警的处理思路
CPU使用率过高应该是最常见的报警之一。但CPU高不等于服务器出了问题,也可能是业务量增长导致的正常现象。处理的关键在于区分这是“突发性”的还是“趋势性”的。
我遇到过一台Web服务器,每天下午三点左右CPU就会飙到90%以上,持续十几分钟后恢复正常。一开始我们以为是定时任务导致的,查了一圈crontab没发现异常。后来用top命令看实时进程,再用perf top采样,发现是一个PHP脚本里的某个循环在特定条件下变成了死循环。原来那个脚本处理某个报表数据时,如果传入的日期参数格式不对,会陷入一个无限重试的逻辑。下午三点恰好是某位业务人员习惯手动触发报表的时间,他经常输错格式,就把CPU给打满了。修复了那个参数校验逻辑之后,报警再也没出现过。
处理CPU报警时,建议你先看整体负载和CPU使用率的分布。top命令里能看到us用户态、sy系统态、wa IO等待、id空闲这几个数值。如果us很高,说明应用层计算密集如果是sy很高,可能是系统调用频繁或者内核线程异常。如果是wa很高,那就不是CPU本身的问题,而是磁盘IO在拖后腿。
还有一个容易被忽视的点是“CPU steal time”。在云主机环境下,如果你的宿主机超卖严重,其他虚拟机争抢物理CPU资源,你会看到st这个指标升高。这时候无论你怎么优化自己的应用,性能都上不去,因为根本原因是云平台资源争抢。你不应该在自己的层面浪费时间,而应该考虑迁移到负载更低的物理节点上,或者升级为独享核的实例类型。
具体到处理步骤,当你确定CPU报警是应用层导致的,最直接的办法是用top或htop找到占用最高的进程,记下它的PID。然后用perf或者strace去追踪这个进程在做什么,同时查看应用的日志,看看有没有大量的错误重试或者死循环。如果一时半会定位不到根因,而业务已经受影响,可以考虑临时扩容或者将流量切到备用节点,给自己争取排查的时间。
内存报警,别只盯着用了多少
内存报警往往比CPU报警更棘手,因为内存问题常常是积累性的。你今天看内存占用70%,觉得还安全,可能第二天它就涨到85%,第三天直接触发OOM,进程被系统杀掉。
我曾经负责过一个Java应用,它的内存使用曲线就像上台阶,每两三天跳一个等级,最后到周五晚上准时崩溃。起先我们以为是内存泄漏,用MAT分析了堆转储文件,发现并没有明显的泄漏对象。后来看了云主机的监控,发现这个应用的JVM堆内存配置和容器内存限制没配合好。JVM的Xmx设置了4GB,但云主机的内存一共才4GB,操作系统和其他进程还要占一部分,实际可用内存不到3.5GB。当JVM尝试申请超过物理内存的范围时,系统开始使用swap交换分区,而swap的读写速度极慢,导致整个服务响应延迟飙升,最终被OOM Killer选中杀掉。解决方法是调整JVM参数,把Xmx降到3GB以下,同时给云主机增加了1GB内存,问题彻底解决。
还有一个真实案例。某台缓存服务器的内存报警显示使用率95%,但我们知道Redis本身就会尽量占用所有可用内存来做缓存,这是正常现象。如果是这种情况,你反而不需要过度担心,只需要关注内存的逐出策略和命中率。如果内存报警伴随命中率急剧下降,说明热点数据被挤出了,需要扩容或者优化key的设计。如果命中率正常,只是单纯的内存使用率高,那是Redis的“本职工作”,你大可不必半夜爬起来处理。
处理内存报警时,建议先用free -h查看内存和swap的使用情况,用ps aux --sort=-%mem列出内存占用最高的进程。然后判断这个进程的内存增长是业务正常需求还是泄漏。如果是泄漏,可以先用jmap或者gdb做一次堆转储,也可以直接重启进程临时恢复服务,但一定要保留现场后续分析。对于云主机,还需要注意内存超分的情况,有些云厂商允许内存超卖,你的实例虽然显示内存充足,但实际可用的物理内存可能因为邻居争抢而不稳定。
磁盘报警,小心“写满即死”
磁盘空间耗尽导致的报警,可能是所有报警里最容易引发直接服务中断的。因为磁盘一旦写满,不仅是你的应用写不了日志和临时文件,数据库无法写入新数据,连操作系统的一些基本功能都会异常。
我亲身经历过一次非常狼狈的磁盘报警。那是一个周六的早晨,我还在睡梦中,被客户的电话吵醒,说他们的上传功能全部失效。登录服务器一看,根分区的使用率达到了100%。具体是什么占用的呢我用du -sh /* 逐层排查,发现在/var/log/nginx目录下有一个access.log文件,大小超过了80GB。原来Nginx的日志轮转配置被人注释掉了,日志文件疯狂增长,最终把整个磁盘填满了。
我当时做的第一件事不是删除文件,而是先弄清楚这个文件是否还在被Nginx进程打开。因为如果一个进程正在持续写入一个已经删除的文件,磁盘空间并不会立即释放,只有重启进程或者用truncate命令清空才行。我用了lsof | grep deleted命令,果然看到这个access.log虽然被删了,但Nginx的主进程还握着它的文件句柄。最后用truncate -s 0 /var/log/nginx/access.log配合nginx -s reopen才真正释放了空间,服务恢复了。
磁盘报警的处理分为几种情况。如果是普通的数据分区或者日志分区,你可以用ncdu或者du命令快速定位大文件和大目录,确认可以安全清理后执行删除。但如果你发现是数据库的数据目录满了,千万不要直接删除文件,那很有可能导致数据库损坏。正确做法是登录数据库,通过alter table或者optimize table来回收空间,或者添加新的磁盘并迁移数据。如果是binlog或者慢查询日志占满,你可以通过设置expire_logs_days来让数据库自动清理过期的binlog。
另外,很多云主机支持在线扩容磁盘,这是最省事的办法。但扩容之前一定要做好数据备份。我有个同事曾经在扩容时操作失误,误删了分区表,几天的数据丢了,差点酿成大事故。
网络和带宽报警
网络类的报警表现形式很多,比如入带宽过高、出带宽打满、丢包率上升、TCP重传率高等。这类报警的处理逻辑和前面不太一样,因为网络往往是端到端的问题,不单是你的云主机能控制的。
有一次我们的对象存储网关报警,说出带宽持续超过了购买的峰值。一开始我们认为是业务量增长导致,准备升级带宽。但后来仔细一看带宽的构成,发现大部分流量来自一个固定的客户端IP。排查发现是某个开发人员写了一个数据导出脚本,循环从存储网关拉取大量数据,又没有加限流。这个脚本跑了几个小时,把公司内网到云端的带宽全占了,影响了其他正常业务。我们找到他停了脚本,报警解除。后来在云主机安全组里对这个IP做了限速策略,防止类似情况再次发生。
如果遇到丢包率或TCP重传率报警,问题更复杂。我曾经处理过一个案例,应用团队反馈说服务器的响应忽快忽慢,监控显示TCP重传率高达5%。我们在云主机上用traceroute和mtr跟踪路由,发现某两个运营商之间的骨干节点有15%的丢包。这种问题你没办法在云主机上直接修复。我们能做的要么是切换线路,比如使用BGP多线或者专线要么是在应用层做重试和容错,用更短的心跳间隔来快速检测失败链路。
处理网络报警时,我建议你先判断是入方向还是出方向的问题。入方向带宽高,说明大量请求涌向你的服务器,可能是正常业务高峰,也可能是DDoS攻击。如果是攻击,你需要紧急开启云服务商提供的高防或者流量清洗服务。出方向带宽高,多半是你服务器往外发送了大量数据,比如大文件下载、数据库导出、日志推送到外部系统等,需要定位是哪个进程或服务产生的流量。
一个非常实用的命令是nethogs,它可以按进程实时显示网络流量。有一次我们用这个命令发现一个备份进程在非备份时间也占用着大量带宽,查出来是cron配置写错了,把每小时备份写成了每分钟备份,幸好及时发现,否则那个月的流量费用就“爆炸”了。
进程和端口报警
这一类报警通常表现为“进程挂了”、“端口不再监听”、“健康检查失败”。处理起来相对直接,但也要注意背后的原因。
我记得有一次,半夜接到报警说Nginx进程不存在了。登录服务器一看,Nginx确实退出了,但systemctl status nginx显示的是“failed”。自己手动重启,服务又恢复了。如果只是简单地重启就完事,那这个报警就白报了。我花了点时间查看Nginx的错误日志,发现里面有一条“upstream timed out”之后紧接着就是“segmentation fault”。进一步追溯内存和core dump,发现是一个第三方模块在特定请求条件下触发了空指针。我们将那个模块升级到最新版本,才从根本上解决了问题。
处理进程报警时,别着急重启,先看日志排查进程退出的原因。如果是被OOM Killer杀掉,dmesg里会有记录。如果是panic或者segmentation fault,一般会有core文件或者堆栈信息。如果是被其他进程误杀,检查是否有监控脚本或者安全软件在干预。如果是数据库等关键进程退出,还要确认数据完整性,必要时从备份恢复。
端口监听报警则要检查端口是否真的在监听,以及监听的地址是否正确。我们之前遇到过,一个Node.js应用监听端口时用了localhost,结果外部健康检查始终失败,但应用本身是正常的,只是网卡地址没绑定对。还有一种情况是端口被别的进程占用了,比如你重启服务时之前的进程没彻底退出,新进程起不来,也会触发端口报警。使用netstat -tunlp可以快速查看端口占用情况。
报警风暴和告警沉默
比起单个报警,更让人崩溃的是报警风暴。也就是短时间内上百条报警同时涌进来,你的手机一直震动,监控大屏全是红色。这时候你已经分不清哪个是根因,哪个是衍生报警。
我经历过一次严重的事故,一台核心数据库云主机因为IO延迟升高,导致依赖它的几十个微服务全部超时,每个超时服务都触发了自己的报警,再加上网络检测、进程监控、业务指标监控,总报警数超过了三百条。团队所有人都在看不同的报警,乱成一锅粥,结果白白浪费了二十分钟,最后才发现根源是数据库所在的云磁盘出现了性能瓶颈。
从那以后,我们强烈建议在处理报警之前,先做“报警聚合”。也就是先看一眼监控系统的根因分析或者拓扑图,找出最早发生的那条报警,或者找到被最多下游依赖的那个节点。通常那个节点就是问题的根源。另外,云主机自带的监控平台往往有事件关联分析功能,它会告诉你当前报警是否跟其他组件的健康状态变化有因果关系。
还有一个实践是设置报警依赖。比如如果数据库主机已经报警了,那么所有依赖它的应用报警应该被自动抑制或者降级为通知。我们不用在半夜两点同时处理二十个报警,只需要集中精力恢复数据库,数据库好了,其他的自然就跟着好了。
善用报警历史做复盘
每一次报警都是一次学习的机会。我每个月底都会把当月的重要报警拉出来看一遍,不是去批评谁,而是找出那些“反复出现的报警”,然后问问自己:为什么这个问题隔几天就发生一次我们能不能通过修改配置或者优化代码,让它彻底不再报警
有一个报警让我们头疼了整整两个月:某台云主机每隔三四天,凌晨一点就会有一次磁盘IO延迟突然升高,持续五分钟后又恢复正常。每次我们白天排查都找不到原因,因为监控里一切正常。最后我们用长期性能分析工具,把一周的数据全部拉出来,发现IO延迟升高的时间和云厂商的定期快照任务完全吻合。原来那台云主机开启了每日自动快照,快照开始时会对磁盘产生额外的IO压力。我们把快照时间从凌晨业务低峰期改到了更早的午夜,并且开启了快照的“不影响IO”模式,这个报警就再也没有出现过。
所以,处理报警不仅仅是“恢复服务”,还要考虑“如何让这个报警以后不再产生”。如果报警是有价值的,就保留它,优化它的阈值和通知方式如果报警是冗余的、没有实际作用的,比如磁盘使用率在凌晨短暂超过85%很快又降下来,这种报警完全可以调整成持续五分钟以上才触发,或者提高阈值到90%。
总结
云主机异常报警的处理,说白了就是一个系统性的故障定位和修复过程。收到报警先冷静,看清楚报警内容和上下文,判断影响范围和紧急程度。然后分门别类地使用对应的工具和方法:CPU高了看top和perf,内存高了看进程和swap,磁盘满了看大文件和使用中句柄,网络异常看iptraf和mtr,进程挂了看日志和core dump。
更重要的是,不要让每一次报警都变成“重启大法”或者“临时扩容”。花点时间找到真正的根因,或许是代码bug,或许是配置不合理,或许是云平台特性导致的限制。把这些根因解决掉,你就会发现那些让你夜里惊醒的报警会越来越少。
最后,我想说,报警不是敌人,它是你在云上复杂环境中的哨兵。良好的报警体系加上冷静的处理流程,能让你的云主机跑得更稳、更放心。




使用微信扫一扫
扫一扫关注官方微信 

