新闻详情

新闻详情

首页 / 资讯中心 / 详情

Linux服务器故障急救指南:从内存耗尽到网络假死的排查流程

发布时间:2026/10/1 17:44:58来源:尧图网络
Linux服务器故障急救指南:从内存耗尽到网络假死的排查流程
凌晨两点半手机连着响了三声我就知道大事不好——客户那边的主机全挂了。SSH敲下去十五秒没有任何反应ping包时通时断监控面板上一排红色的告警。搞Linux服务器运维的朋友应该都有过这种经历白天的小隐患不当回事半夜的系统崩溃教你重新做人。今天我打算把自己这些年抢救Linux服务器时总结的一整套故障排查流程完完整整讲一遍。说“实战演练”不是标题党下面每一段都是真实场景覆盖了日常运维中最常见的四类致崩因素内存耗尽、磁盘占满、进程失控、网络假死。无论你是刚接手Linux服务器的新手还是已经带过集群的资深运维这份急救指南都建议收藏真出问题的时候照着一步步来能省下大量试错时间。1. 到现场的第一件事先分清是真死机、假死机还是服务挂了很多人一听说服务器崩溃立刻就开始敲各种命令结果越敲越乱。我踩过这个坑所以现在养成了一个习惯先花两分钟搞清楚故障形态再决定后续动作。因为“崩溃”这词太宽泛了你面对的可能完全是三种东西。1.1 三种故障形态的判断特征第一种是彻底宕机。物理机断电、内核panic、硬件故障系统完全停止运转。表现是ping都不回机房告警或者云控制台显示实例已停止远程任何操作都做不了。第二种是假死。系统还在运行CPU、内存、磁盘其中某个资源被打满导致整个系统响应极慢SSH能建立连接但敲命令半天不回显或者干脆连登录都卡在密码阶段。这种最容易让新手误判成“服务器坏了”实际上系统内核还活着只是被资源耗尽拖住了。第三种是系统层面正常某个关键服务进程挂了。这时候你ping得通、SSH也流畅但网站打不开、数据库连不上、业务接口全部超时用户感知就是“服务器崩了”。判断的方法很简单按顺序来先ping再尝试SSH端口再试应用端口最后看系统状态。ping不通大概率是第一类ping通但SSH连不上大概率是第二类SSH没问题但业务失败就是第三类。把这层分清楚你后面排查的方向才不会跑偏。1.2 物理机和云服务器的远程救援入口判断完形态接下来要解决的是“我怎么进去”。如果是彻底宕机纯软件手段已经无效必须借助带外管理入口。物理机一般看厂商的BMC管理口比如Dell iDRAC、HP iLO、华为iBMC登录进去先看硬件状态面板——电源灯、风扇转速、温度告警、RAID卡状态很多硬件崩溃一眼就能锁定。云服务器则用云控制台的VNC登录相当于直接接了一个显示器可以绕过网络层看到服务器真实状态。我见过不少同事在SSH不通的时候反复重试其实这时候早该切到VNC去看系统到底卡在哪里了。1.3 能进系统后的第一轮快查如果还能登录哪怕很慢也要先执行三个命令把现场固定下来uptime dmesg | tail -50 journalctl -p err -buptime看负载历史和运行时间dmesg看内核最近的报错journalctl只看本次启动的错误日志。这三个命令能在十秒内帮你判断系统是不是刚重启过、内核有没有panic、硬件有没有报错。下次再遇到类似情况哪怕一时找不到原因这一步的日志也会是你复盘的关键线索。记住一个原则急救阶段不要乱动先快照日志再做修复动作。很多被干掉的证据都是因为操作者一上来就重启或者kill进程把最后的诊断机会浪费掉了。2. 内存耗尽与OOM Killer系统没“死”但卡到没法用这类故障出现频率极高特征也非常典型服务器缓慢如蜗牛输入命令要等十几秒才回显业务日志里疯狂报连不上数据库用户端一片哀嚎。但系统并没有真正死掉因为CPU可能还是空闲的问题出在内存上。2.1 先搞清楚Linux到底是什么时候开始“杀进程”的Linux系统在内存分配上不是等物理内存彻底用光才着急它把内存管理交给内核由内核判断什么时候内存紧张到必须回收。当系统内存耗尽且swap也没有空间内核就会启动OOM Killer也就是Out Of Memory机制挑一个进程杀掉来释放内存。这个“挑选”的逻辑很多人不理解。它不一定是杀占用内存最大的进程而是根据一个综合评分叫oom_score这个值会考虑进程的内存占用、运行时间、进程优先级等。站在运维角度你只需要知道两点一是内存耗尽会由内核来“处决”进程而不是系统直接崩溃二是被杀的往往是数据库、Java应用这类大内存进程因为分数高。所以你会看到一种很诡异的现象服务器的系统还活着但MySQL进程没了Nginx进程没了业务彻底瘫痪。这就是典型的OOM事件。2.2 用日志还原被杀现场发生OOM后第一件事不是着急重启服务而是去确认“到底是谁被杀了为什么被杀”。日志里面写得清清楚楚。dmesg -T | grep -i -E killed process|out of memory journalctl -k --since 2 hours ago | grep -i oom正常你会看到类似这样的输出Out of memory: Killed process 25641 (mysqld), total-vm: 8456400kB, anon-rss: 3124700kB这一条记录就是整个事故的起点。记下这个进程名、PID、时间点后面所有排查都要围绕“为什么内存会不够”展开。切记不要蒙头就把MySQL拉起来因为内存压力还在起来一个杀一个最后变成僵尸循环。真正要做的是看内存到底被谁吃掉了。先看整体水位free -h如果available已经很低再用ps aux --sort-%mem | head -20看看当前内存占用最高的进程同时结合top观察几轮留意RES这一列的涨幅。内存泄漏往往不是一瞬间的而是某个进程的常驻内存不断往上爬几个小时后把系统拖垮。2.3 泄漏定位与临时救治确认是某个进程内存持续增长后就要判断是不是代码级泄漏。Java进程可以抓heap dumpNode进程可以做heap snapshotMySQL和Redis就检查连接数和缓存配置。如果现场紧张来不及分析我的习惯是先把服务按依赖关系停掉从前到后逐个隔离每停一个就看free -h内存有没有明显回落。临时救治的办法有两个一个是重启那个异常进程释放内存另一个是调整内核行为避免它继续被杀。但这里要特别说一个常见误区很多人一上来就sync echo 3 /proc/sys/vm/drop_caches想靠清理缓存来救急。这个方法对释放内存没有实际作用因为那部分缓存本来就可以由内核自动回收真正的压力来自应用程序占用的匿名内存你是drop不掉的。如果内存压力严重临时扩容是唯一有效手段物理机可以加swap。我在一台内存特别吃紧的服务器上用过swap扩容的办法fallocate -l 4G /swapfile chmod 600 /swapfile mkswap /swapfile swapon /swapfile加到/etc/fstab之前先想清楚swap只是应急不是长期方案内存问题的根治还是得靠查泄漏和扩内存。为什么还要临时加因为当务之急是把业务先拉起来之后才有时间慢慢分析。2.4 防止OOM反复出现的几个关键参数处理完现场想避免同样的坑有几个内核参数值得细调。vm.swappiness控制系统使用swap的倾向默认值通常60对数据库服务器或者内存充足的应用服务器调到10左右更合理。vm.overcommit_memory这个参数要小心改成2表示禁止内核过度分配内存能降低OOM风险但也可能让大内存应用直接启动失败。更推荐的方式是用systemd为单位配置MemoryMax把内存限制到容器或服务级别比全局内核参数更可控。我在实际运维中还会专门观察一个问题swap是否被大量占用。如果free里si和so两列一直在跳动说明系统内存严重不够物理内存已经顶不住压力了这时候光调参数没用扩容才是正路。3. 磁盘占满与IO阻塞大多数崩溃其实早有预兆这一类是教科书上写得最少、但实际工作中遇到最多的。相比内存崩溃的“暴风骤雨”磁盘问题往往是“温水煮青蛙”。你平时不注意某一天它突然就炸在你面前。3.1 df -h明明显示还有空间却报“No space left on device”新手最迷惑的就是这个场景。df -h显示根分区还有20%可用但写文件就是报磁盘已满。原因大概率出在inode上。inode可以理解成文件系统里存放文件元数据权限、所有者、大小、位置等的索引节点一个文件至少要占一个inode如果分区里的文件数量多到把inode池消耗干净即使还有剩余磁盘块系统也无法创建新文件。遇到这种情况排查命令很简单df -h # 看容量 df -i # 看inode如果df -i的IUse%到了100%恭喜你找到根本原因了。这通常发生在某个目录堆积了大量小文件比如程序日志碎片、任务产生的临时文件、邮件队列一个几GB的分区里可能躺了几百万个几KB的小文件。3.2 用命令把占用空间的“隐藏大佬”揪出来定位大文件的标准操作是逐层du别在系统繁忙的时候用大范围扫描最好先锁定可疑目录再深入du -h --max-depth1 / 2/dev/null | sort -rh | head -10 du -h --max-depth1 /var 2/dev/null | sort -rh | head -10这样一层层下去最多四层就能找到真正占用空间的位置。还有一个经常被忽略的点文件已经被进程删除但进程还持有句柄导致磁盘空间一直释放不了。用lsof | grep deleted查看找到那个进程重启它或者重启服务空间才会真正释放。这里插一句我的切身体会很多人清理磁盘习惯性地rm -rf一顿删结果删完df -h一看空间没变第一反应是命令没生效其实是被占用文件在“拖后腿”。所以清理之前先跑lsof | grep deleted能省很多困惑。3.3 一次性大文件与日志轮转的兜底如果发现是日志文件撑爆了磁盘而且业务还在持续写入简单删除可不管用——刚删完日志又写满了。标准做法是配置logrotate让日志按天或按大小轮转保留最近N份自动压缩归档。我的习惯是为所有写入量大的日志目录都加上轮转策略比如对/var/log/nginx目录下所有日志做按天轮转保留7天这基本能把日常日志增长控制在一个安全范围。3.4 IO阻塞磁盘负载高时的表现和定位磁盘满之外还有一类故障是“磁盘没满但读写慢到窒息”。它最典型的特征是load average很高但CPU使用率很低top里看到一堆进程处于D状态也就是不可中断睡眠绝大多数情况是在等磁盘IO。我用iostat -x 1看磁盘利用率重点看%util和await两列。%util接近100%说明这块盘确实忙不过来await数值很高说明IO请求在排队。用iotop可以进一步定位到是哪个进程在疯狂读写磁盘。这类故障最容易出现在数据库服务器上尤其是慢查询、全表扫描、未命中索引的SQL把磁盘读爆。还有一种情况是备份程序在业务高峰时段跑全量备份把磁盘带宽占满。我在集群里就遇到过每周日凌晨的备份任务和业务高峰冲突直接把IO拖到堵车。解决办法是错峰执行同时限制备份任务的IO优先级用ionice -c 3把备份进程设为仅空闲时执行业务高峰期的IO就能喘过气来。3.5 磁盘清理的底线原则最后必须强调一个安全底线千万别在生产服务器上执行rm -rf /这类命令也尽量避免在根目录下做全局通配符删除。我见过不止一次因为命令写错路径导致整个系统被删空的事故。清理磁盘的正确姿势是先定位精确路径再列目录确认最后才执行删除并且删除前最好给关键数据留个备份。4. 进程失控与僵尸进程CPU飙到100%却不一定有“真凶”排除掉内存和磁盘问题后还有一大类崩溃来自进程本身。业务进程CPU占用飙到100%请求堆积响应超时或者进程彻底僵死想杀杀不掉。这类问题定位难度中等但很容易走弯路。4.1 load average的真实含义CPU疯了还是进程堵了很多人一看到load average超过核心数就觉得CPU不够了立刻去扩容。这个判断有时候是浪费钱的。load average反映的是“处于可运行状态和不可中断状态的进程平均数”它高可能是CPU忙不过来也可能是大量进程卡在IO等待上还可能是有太多进程在排队。我判断的方法是搭配看top里的%Cpu(s)这一行。如果us和sy占比很低但load很高说明进程多半是堵在别的地方比如IO、锁、网络而不是CPU本身。这种情况下加CPU核心数毫无意义。先把负载高的根因找到再决定要不要扩容。4.2 手把手定位失控进程如果确实是某个进程把CPU吃满了用top按P排序然后盯住那个PID看它的CPU时间是不是持续增长。如果持续飙高就可以确认是它的问题。接下来用ps看细节ps -eo pid,ppid,stat,comm,%cpu,%mem,etime --sort-%cpu | head -20重点看STAT这一列。R表示正在运行D表示不可中断的IO等待Z是僵尸进程。R状态加上持续高CPU基本就是死循环或者热循环D状态说明它在等IO根因多半在磁盘或网络。如果是自己写的脚本在跑直接看代码定位死循环就好如果是第三方程序先到项目日志搜最后一条报错。我在环境里遇到过Java应用因为GC日志级别配置错误导致疯狂写日志占满CPU最后发现罪魁祸首是一行日志配置而不是业务代码这种案例非常典型。4.3 僵尸进程为什么杀不掉僵尸进程状态为Z是子进程已经结束但父进程没有回收它的退出状态码所以它在进程表里占了一个位置但不再占用CPU和内存。kill -9对它无效因为一个已经死掉的进程是无法被“再杀死”的。处理僵尸进程的正确思路是找到它的父进程让父进程来收尸。用pstree -p看看父子关系如果父进程是init或systemd通常系统会自动回收但如果你发现僵尸进程的父进程是一个长期运行的服务进程而它还一直不回收那就要考虑是不是父进程本身有bug或者父进程在处理子进程退出时卡住了。这时候更务实的做法是重启父进程对应的服务。4.4 用strace给进程做“核磁共振”当进程不崩溃但行为异常时strace是最强大的诊断工具。它可以跟踪进程的系统调用相当于给进程做核磁共振看它到底卡在哪里。strace -p 12345 -f -e tracenetwork,file,desc -o /tmp/trace.log第一次跑的时候别贪多专心看上头的几个调用。我之前诊断过一个服务“假死”的故障业务进程CPU低得可怜但就是回不了响应。strace发现它卡在了一个futex调用上再配合线程转储确认是代码里一把锁没释放造成线程死锁。没有strace这个问题几乎无法定位。不过要提醒一句strace有性能损耗尤其是跟踪多线程进程时会让服务明显变慢。生产环境如果进程还能响应只是性能差建议慎用strace可以先用perf top看内核热点再做系统调用层面的诊断。5. 网络层面的“假崩溃”端口通着服务却废了还有一种非常隐蔽的故障服务器系统正常磁盘内存CPU全没问题但客户端就是连不上。你登录服务器发现一切如常打开端口也是监听状态可业务就是进不来。这种“假崩溃”通常要怪网络层的某个细节。5.1 分层排查法从链路到应用的四个台阶这类问题我建议按层次从下往上排查每一步都先明确目标再动手不要东一榔头西一棒子。第一层物理链路和基础连通性用ping确认主机通不通。第二层端口层用nc -vz 服务器IP 端口或者telnet测试端口是否开放。第三层应用层用curl访问HTTP接口看返回状态码或者用数据库客户端测试连接。第四层应用日志查询这个服务近期有没有报错尤其是连接相关的错误比如“Too many open files”和“Connection refused”有本质区别。我遇到过很多次“端口监听正常但连接就是进不去”的情况。问题出在防火墙规则更新或安全组误操作上这时候你用iptables -L -n -v检查规则或者去云控制台查看安全组很容易发现刚才有人偷偷加了一条拒绝策略。5.2 文件描述符与连接状态Nginx和数据库“猝死”的幕后推手系统层面的socket数量和文件描述符限制也是故障高发点。每个TCP连接都占用一个文件描述符而一个进程能打开的文件数默认往往只有1024或65535一旦连接数超过这个数字服务就会报错甚至拒绝新连接。这个故障最典型的报错是“Too many open files”。排查方式非常直接ulimit -n # 当前限制 ss -s # 查看当前的socket统计 ss -snt | awk NR1 {print $1} # 查看各状态连接数如果发现TIME_WAIT或者CLOSE_WAIT堆积特别多就要考虑连接池配置不合理或者服务端没有正确关闭空闲连接。TIME_WAIT本身不算错误但过多会占用大量端口和内存。调整内核参数net.ipv4.tcp_tw_reuse和net.ipv4.tcp_fin_timeout可以缓解但根本解法还是要优化业务代码的连接管理。还有一个小细节。Nginx的worker_connections和proxy_pass后端的keepalive配置都直接影响单机连接上限。我处理过一个案例一个页面因为前端轮询接口没有使用连接复用导致Nginx后端连接数瞬间冲爆看起来像是服务崩了实际上是用满了连接配额。5.3 日志风暴当系统把磁盘和窗口全写在/var/log里网络假死还有一种极其隐蔽的元凶系统日志风暴。某个服务疯狂向/var/log/messages或journald写入日志每秒上百条导致日志进程占满CPU磁盘IO被打满最终系统整体变慢连SSH都开始闪断。从外面看现象和网络崩溃一模一样。排查命令也很简单先检查/var/log目录的大小再用tail查看最新日志的刷新频率如果每秒都有新条目基本就是某个服务在刷屏。定位到来源后先临时关闭或降低这个服务的日志输出级别等系统恢复后再处理根本原因——通常是配置错误或者业务异常在反复报错。5.4 变更点排查90%的网络故障都是“改出来”的总结这些网络问题我最想提醒的一点是遇到网络假死先问“最近改过什么”。我曾经花一个小时排查一个SSH登录慢的问题最后发现是有人在/etc/hosts里加了一条解析导致DNS查询超时。DNS解析慢、路由链路变化、防火墙规则更新、软件升级后内核参数修改这些变更才是网络故障最常见的源头。所以我现在排查任何网络问题时第一件事就是去看最近的变更记录这比任何工具都管用。6. 急救之后的复盘与加固别白熬一个通宵故障处理完、业务恢复后很多人会觉得“搞定收工”直接补觉去了。这是最浪费事故价值的行为。每场故障都是系统最诚实的体检报告不好好复盘同样的坑下次还要再踩一次。6.1 用“三张表”把故障复盘变成可复用的经验我自己的复盘习惯是整理三张表。第一张是“故障时间线”记录每个时间点发生什么现象、做了什么操作、系统有什么反应这样以后回看能准确还原整个演进过程。第二张是“变更登记表”记住故障发生前后一周服务器上的所有变更无论是配置修改、软件升级还是代码发布90%的故障都藏在变更里。第三张是“资源水位表”列出每台服务器的CPU、内存、磁盘、inode、带宽的基线和告警阈值平时不看关键时刻能直接判断出“这数值正不正常”。6.2 告警监控的最小可行方案没有监控的服务器就像没有仪表盘的汽车开着很爽出事全靠直觉。监控不一定非要上全套重型方案最简单可靠的是给每台服务器配上基础的资源监控和告警。我习惯用Prometheus加node_exporter做采集Grafana做展示告警规则里至少覆盖五个指标内存可用率低于20%、磁盘使用率高于80%、inode使用率高于90%、load高于核心数持续5分钟、关键进程消失。如果条件不允许上这套用cron脚本加钉钉或邮件通知也可以核心是“出问题必须有人被叫到”。这里要提醒一句告警阈值不要拍脑袋设得太低否则天天告警最后真出问题时反而没人看了。我的经验是先观察两周正常水位再按正常水位的1.5到2倍设“关注告警”3到4倍设“紧急告警”。6.3 服务守护与资源限制的配置底线防止单点故障和服务崩溃有些系统层面的设置是必须补齐的。用systemd管理的服务一定要配上Restarton-failure和RestartSec3这样进程异常退出后可以自动拉起为人工接手指标争取时间。对内存敏感的进程用MemoryMax做限额防止一个进程泄漏把整个系统拖垮。LimitNOFILE也要按服务并发量调大否则连接数上来就是灾难。最后我还习惯在每台服务器的root目录下放一个rescue.sh脚本把常用的诊断命令打包成一个脚本一键执行把内存、磁盘、IO、进程、网络、最近日志一次性输出到/tmp/rescue.log。真到紧急时刻你不需要背命令只需要跑这个脚本然后把输出丢给同事或者贴到搜索引擎里分析。这是我做了这么多年运维后觉得最实用的小技巧。说句掏心窝的话我这些年最深的体会是大部分所谓“服务器崩溃”都不是一瞬间炸掉的而是被我们一点点忽略的小问题拖垮的。急救只是最后的止损手段真正值钱的是故障发生前你做了多少预防以及故障发生后你有没有把教训转化成下一次不会重蹈覆辙的机制。每次处理完故障我都会留出半小时把那个晚上学到的东西沉淀下来。至少下回手机再响我不会慌。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

SpringBoot+Leaflet实战:行政区划地图掩膜与镂空遮罩实现 2026/10/1 20:15:29

SpringBoot+Leaflet实战:行政区划地图掩膜与镂空遮罩实现

做政务大屏、WebGIS 可视化项目的时候,“行政区划地图掩膜”这个需求我几乎每次都会遇到。客户不会跟你提“掩膜”这么专业的词,他们只会说:把山东这块区域突出显示,其他地方压暗一点。听起来很简单,但真正动手你就会发…

阅读更多 →
基于Flask和微信小程序的课程考勤签到系统设计 2026/10/1 20:15:28

基于Flask和微信小程序的课程考勤签到系统设计

1. 项目背景与核心需求拆解1.1 为什么学校场景需要一套专属考勤系统说句实在话,大学课堂里的点名签到,几乎每个人都经历过。传统的做法无非是纸质签名传递、班长代喊、或者老师拿个名单挨个勾。纸质签到最大的问题在于代签几乎无法杜绝,一张纸…

阅读更多 →
C++冒号用法全解析:从初始化列表到作用域解析 2026/10/1 20:15:28

C++冒号用法全解析:从初始化列表到作用域解析

1. 单冒号“:”——一个字符撑起多种语法场景很多刚接触C的人,看到冒号第一反应是“这不是三目运算符里的那个符号吗”,然后就在各种奇怪的编译错误里反复挣扎。实际上,单冒号在C里是个看起来低调、但登场频率极高的语法符号。它能出现在初始…

阅读更多 →
Flask + TF-IDF 一天搭建新闻推荐系统:文本向量化与相似度匹配全流程实战 2026/10/1 20:15:22

Flask + TF-IDF 一天搭建新闻推荐系统:文本向量化与相似度匹配全流程实战

我先说一个结论:新闻推荐系统,听起来是个很唬人的东西,实际上在算法选择正确的前提下,一天时间真的能搭出一个能用的版本。这个项目我用 Flask 做 Web 层,TF-IDF 做特征提取,走通了“新闻文本 → 向量化 →…

阅读更多 →
SpringBoot + Leaflet 行政区划掩膜高亮可视化实战 2026/10/1 20:15:21

SpringBoot + Leaflet 行政区划掩膜高亮可视化实战

做行政区划类的可视化需求,我猜你迟早会遇到这样一个效果:地图上目标区域高亮显示,周围区域被半透明遮罩压暗,视觉焦点一下子就落到了目标区域上。这个效果在可视化大屏、政务平台、招商系统里非常常见,业内一般叫“掩…

阅读更多 →
WSL安装慢更新失败?换源与离线安装实战指南 2026/10/1 20:15:21

WSL安装慢更新失败?换源与离线安装实战指南

说个真实情况,我最近帮朋友装WSL,连着踩了好几个坑:wsl --install卡在“正在下载”半天不动,wsl --update跑到 40% 就纹丝不动,wsl --list --online直接报“解析失败”。你要是也正在被这几个问题折磨,那这…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉