1. 为什么我建议每个运维都收藏这份排查清单
服务器出故障的时候,最怕的不是故障本身,而是面对一堆报警信息不知道怎么下手。我见过太多刚入行的同事,一看服务挂了就慌了神,又是重启又是重装,折腾几个小时最后发现只是磁盘满了,或者是某个服务忘了开机自启。这种经历经历过一次就知道,一套系统的排查思路比临时百度管用得多。
这篇文章想讲的,是服务器日常运维中最常见的12种基本故障。它们不涉及高深的内核调优,也不需要复杂的监控系统,就是每一个运维、每一个自己鼓捣服务器的开发者都会遇到的典型问题。从硬件层面的开机无响应、内存报错,到系统层面的磁盘爆满、负载过高,再到应用层面的数据库连不上、端口被占用,我都会拆开揉碎了讲一遍,内容包括故障长什么样、一般是什么原因、按什么顺序去查、用什么命令验证,以及我实操中踩过的坑。
不管你是刚接触服务器的新手,还是已经有几年经验的运维,这份清单都可以当成一份落地的手册。遇到问题的时候翻到对应小节,按步骤走一遍,大概率能省下不少折腾的时间。另外,文中所有命令都在常见的 Linux 发行版上验证过,CentOS、Ubuntu、Debian 系都能直接用,Windows Server 的部分场景我会单独标注。
2. 服务器出故障之前,先看懂症状和影响面
在逐条列12种故障之前,我想先说一个更重要的逻辑:排查故障的第一步,永远不是动手改配置,而是搞清楚“这台服务器现在到底是什么状态”“这个故障影响到了谁”。没有这个判断,很容易在小问题上乱打一气。
2.1 怎么快速判断服务器是不是真的“挂了”
有一种很典型的场景,业务方跑过来喊“服务器挂了”,你 ssh 一登,机器明明通着,负载也不高。这时候不要急着反驳,先分清楚是“机器挂了”还是“服务挂了”。
- 机器层面的故障:ping 不通,ssh 连不上,物理机电源灯异常,或者云控制台显示实例运行中但你完全无法访问。
- 服务层面的故障:机器正常,但是某个应用进程没了,端口不响应,数据库连接被拒,网页打不开。
这两类问题的排查路径完全不同。机器层面的问题优先看硬件状态、网络配置、云平台告警;服务层面的问题优先看进程状态、日志文件、端口监听情况。我见过有人花了一晚上重装系统,最后发现只是负载均衡配置把后端摘掉了,这种教训一次就够。
2.2 故障影响面的快速评估技巧
拿到故障通报后,最快评估影响面的方式有三个:看监控面板、看访问日志、看错误日志的时间线。
- 监控面板:CPU、内存、磁盘、带宽有没有明显拐点,如果有,拐点前后的时间差就是故障发生时间。
- 访问日志:nginx 或业务应用的 access log 在某个时间段内,5xx、4xx 比例是否突然升高。
- 错误日志:应用日志中 Exception、Error 级别的输出,通常会在故障前后留下非常完整的现场记录。
我自己的习惯是,收到报警先花两分钟把这三样扫一遍,心里有底了再开始动手。这比直接登录服务器敲命令要高效得多,因为你很可能根本不知道去哪里敲命令。
3. 12种基本故障的完整拆解与排查路径
下面进入正题。这12种故障是我根据这些年实际遇到的情况,按“现象、原因、排查、解决”的框架整理出来的。每一个都能独立成篇,但放在一起看,你会发现服务器出问题其实就集中在几个层级上:硬件、操作系统、网络、应用。
3.1 第1种:机器无法开机或者反复重启
现象:物理机按电源键没反应,或者开机到一半自动重启;云服务器在控制台显示运行中但连不上,重启后依然无法进入系统。
常见原因:内存条接触不良或损坏、电源模块供电不足、主板电容鼓包、系统引导文件损坏、内核 panic 后自动重启。
排查路径:
- 物理机优先看前面板指示灯和报警声,不同品牌(Dell、HP、浪潮、联想)的报错含义不一样,说明书里都有对照表。
- 打开机箱重新插拔内存、显卡、硬盘数据线,这是最简单也最高频见效的操作。
- 能进 BIOS/UEFI 就进去看硬件识别情况,特别是内存容量是否被正确识别、硬盘是否掉盘。
- 如果能启动到 grub 菜单但进不了系统,常见原因是引导损坏,可以用系统安装盘进入 rescue 模式修复。
- 云服务器出现这种情况,优先去控制台看“系统日志”或“VNC 登录”,那里能看到真实的开机过程。
实操心得:很多时候开不了机真的是内存条松了,尤其是机房机器搬迁之后。搬动过的机器出这个问题的概率极高,我建议物理机开机异常第一件事永远是打开机箱看硬件,别一上来就重装系统。
3.2 第2种:磁盘空间不足导致服务异常
现象:数据库写入失败、日志文件突然不更新、临时文件无法创建、服务启动时报 No space left on device,但 df -h 看起来空间还剩不少。
原因分析:空间不足可能不只是“文件大”,还有 inode 耗尽、被删除文件仍被进程占用、分区挂载异常等情况。
排查路径:
- 先
df -h看空间,再df -i看 inode 使用率,两条命令必须一起用。 - 用
du -sh /* 2>/dev/null从根目录往下逐层定位大目录,找到是哪个路径在疯狂增长。 - 用
lsof | grep deleted查看是否有被删掉但还被进程占用的文件。如果有,重启对应进程或服务才能真正释放空间。
运维重点:磁盘爆满不是一次性事件,而是一个过程。平时就要通过 cron 做每日磁盘空间巡检,超过80%就该预警。日志定期切割、归档、清理,数据库备份保留周期要有明确策略,不要等报警了才开始处理。
注意:清理大文件时先确认是什么应用在写,直接删文件不一定有效,有些进程会继续占用句柄,必须重启进程或者 truncate 文件而不是 rm。
3.3 第3种:CPU 负载异常飙高
现象:uptime里的 load average 超过核数好几倍,应用响应变慢,但 top 命令看到的 CPU 使用率却不是特别高。
原因分析:load average 高既可能是 CPU 密集型任务,也可能是不可中断睡眠的进程太多,比如磁盘 IO 卡住了,进程在等 IO,这种状态也会计入 load。
排查路径:
top -c按 CPU 排序,看哪个进程最吃 CPU。按数字 1 看每个核心的使用情况。- 如果 CPU 使用率低但负载高,用
iostat -x 1看磁盘 %util 和 wa 的值,判断是不是磁盘慢拖累了整个系统。 - 用
ps aux --sort=-%cpu | head -20拿完整的进程列表。 - 如果是云服务器,还可能是同物理机上的邻居吵闹,这种情况看监控曲线通常会有规律性。
解决思路:应用层 CPU 高,就优化代码逻辑或者扩容;进程异常导致的高占用,先确认是不是被入侵,再做处理;磁盘 IO 导致的假负载,核心问题在磁盘,去看第5种故障。
3.4 第4种:内存耗尽触发 OOM Killer
现象:某个应用进程突然消失,/var/log/messages 或 dmesg 里有 Out of memory 的字样,系统服务变得极不稳定。
原因分析:应用内存泄漏、并发量过大、JVM 或脚本引擎堆内存设置不合理、Swap 配置过小或未配置。
排查路径:
free -h看内存总量和 Swap 使用情况,top查看进程中 RES 和 VIRT 占用。dmesg | grep -i oom查看操作系统杀掉了哪个进程,这是最重要的现场证据。- 如果 Java 应用经常出问题,用 jmap 导出堆内存做分析,排查是否有对象没有被回收。
- 给关键服务配置 systemd 的 OOMScoreAdjust 或修改 oom_score_adj,让系统在极端情况下优先保留重要进程。
实操心得:OOM 最坑的地方是,系统把进程杀了之后表面上看日志只会有简单的 Killed process,如果不看 dmesg 根本找不到凶手。另外,别以为加内存就解决一切问题,内存泄漏的代码在 512G 的机器上一样能爆。
3.5 第5种:磁盘 IO 延迟过高或吞吐骤降
现象:数据库查询无故变慢、文件读写卡顿、iostat 显示 %util 接近100%,但应用日志里看不到明显的报错。
原因分析:机械盘老化坏道、SSD 寿命耗尽、RAID 组重建期间性能下降、批量任务瞬间写入太大、云磁盘类型本身 IOPS 就有限。
排查路径:
iostat -x 1看每个磁盘的 rkB/s、wkB/s、%util、await 值。%util 高不一定有问题,还得看 await 是否比平时高。iotop定位是哪个进程在大量读写磁盘。- 检查是否在跑数据库全量备份、日志清理、批量数据导入之类的定时任务。
- 云硬盘看监控面板的 IOPS 和吞吐量指标,超出规格限制会出现排队。
解决思路:如果确认是磁盘性能不够,解决方案无非是提升磁盘规格、把热点数据放到缓存、优化 SQL 减少扫描量、把批量任务错峰执行。如果坏道导致的 IO 错误,做好备份之后及时更换硬盘。
3.6 第6种:网络不通或丢包严重
现象:服务器 ping 不通、ping 通但 TCP 连接超时、丢包率忽高忽低、外网访问非常慢。
排查路径:
- 从自身链路开始查,
ip addr确认 IP 配置没问题,ip route确认默认路由存在。 ping 网关确认本机到网关是否通,如果网关都不通,问题在物理链路或虚拟网络配置。ping 公网 IP(比如 223.5.5.5)确认外网出口是否正常。注意一定要 ping IP,不要 ping 域名,这样能区分 DNS 问题和网络问题。- 丢包就用
mtr 目标IP分段看是哪一跳出了问题。自建机房的机器注意检查交换机端口模式是否匹配。 - 安全组/防火墙规则、iptables 和云平台的网络 ACL 也要一并核查,很多“网络不通”实际上是访问控制被拦了。
常见坑:服务器本地 ping 自己的公网 IP 是通的,但外网访问不了,这种情况多半是云平台安全组没放行对应端口。不要先怀疑系统防火墙,先看安全组外到内的规则。
3.7 第7种:SSH 无法连接或频繁断开
现象:ssh 登录卡在输入密码前的那一步、连上去没多久就断线、连接被拒绝,或者是提示 Host key verification failed。
排查路径:
- 先确认 sshd 服务是否在运行,
systemctl status sshd查看状态。 - 确认 22 端口是否在监听,
ss -lntp | grep 22。 - 检查 /var/log/secure 或 /var/log/auth.log,看有没有认证失败的记录,这能区分是密码错误、网络问题还是有人爆破导致被 fail2ban 拉黑。
- Host key verification failed 经常出现在重装系统之后,清掉本地 known_hosts 里对应的旧记录再连。
- 云服务器还要检查安全组是否放行了 22 端口,源 IP 是否限制得过死。
经验之谈:如果你经常性地需要连一台机器,强烈建议用密钥认证而不是密码。配置好之后不仅省去输密码的麻烦,还能在 sshd_config 里把 PasswordAuthentication 关掉,减少爆破风险。至于很多人问的“怎么每次连服务器不输入密码”,就是密钥对里的公钥放到服务器的 authorized_keys 文件里,本地私钥留好,权限一定要设置正确(私钥 600,~/.ssh 目录 700)。
3.8 第8种:服务进程崩溃或自动退出
现象:某个进程运行一段时间就自己退出了,systemd 管理的服务会反复重启,应用日志的最后几条记录很突然。
排查路径:
- 看 systemd 日志:
journalctl -u 服务名 -n 100 --no-pager。 - 查应用日志文件里最后的异常堆栈,特别是 OutOfMemory、Segmentation fault、Aborted 这类关键词。
- 如果是 Java 应用,带上 -XX:+HeapDumpOnOutOfMemoryError 参数,崩溃时自动生成 dump 文件,事后分析。
- 如果是编译型语言,检查是否因为内存越界导致 core dump,配合 gdb 看堆栈。
- 排查是否有外部定时任务或监控脚本把它停了,比如
kill、pkill、重启策略等。
实操心得:systemd 的 Restart=on-failure 配置是双刃剑。进程崩溃后自动拉起确实省心,但对于需要维护状态的进程,频繁崩溃重启会造成更多数据不一致的问题。我建议线上服务先关掉自动重启,人工确认原因后再拉起来,不然你会被无限重启的日志淹没。
3.9 第9种:数据库连接数或端口被占满
现象:应用报 too many connections 或 Connection refused,端口检查发现大量 TIME_WAIT 或 ESTABLISHED 连接,服务端口无法绑定。
原因分析:应用连接池配置过大、慢查询堆积导致连接长期不释放、短连接请求量过高、连接泄漏没关闭、数据库 max_connections 设置偏小。
排查路径:
ss -s看系统连接统计,ss -ant | awk '{print $1}' | sort | uniq -c看各连接状态数量。- TIME_WAIT 太多可以调整内核参数 net.ipv4.tcp_fin_timeout 和端口范围 net.ipv4.ip_local_port_range,但根本办法还是让应用尽量用长连接。
- MySQL 中执行
show processlist查看当前连接在干什么,有没有大量 Sleep 空连接。 - 把应用连接池的最大值调到一个合理区间,并设置连接空闲回收时间。
经验之谈:有一回排查一个“端口被占满”的问题,服务器上根本没几个服务,最后发现是日志收集 Agent 的 HTTP 连接没走代理,每次上报都新建一个 TCP 连接然后堆积成 TIME_WAIT。问题不在服务器,而在客户端的使用方式上。
3.10 第10种:系统时间偏差过大导致认证和同步失败
现象:HTTPS 证书校验失败,输密码登录服务器提示认证错误,集群节点间通信报时间戳异常,定时任务执行时间与预期不符。
原因分析:服务器没有配置时间同步,或者配置的时间服务器不可用。
排查路径:
date -R看当前时间和时区。timedatectl查看 NTP 同步状态,确认 NTP synchronized 是否为 yes。- 手动执行
chronyc sources -v或ntpq -p查看时间源是否处于可达状态。
解决思路:在 Linux 服务器上装 chrony 并配置好可靠的时间服务器,然后开启开机自启。云服务器可以直接用云平台提供的内网 NTP 地址,自建机房可以用国内的时间服务器地址。时间同步这个问题看似不起眼,但证书校验、分布式事务、日志排障全都依赖它,必须重视。
提示:如果修改了时区,记得也要同步修改 crontab 里定时任务的执行时间,否则按旧时区算的任务会在错误的时间点执行。
3.11 第11种:硬件告警,风扇、电源、温度异常
现象:物理机前面板亮黄灯报警,IPMI/带外管理系统推送风扇转速异常或温度过高告警,机房巡检发现噪音变大。
排查路径:
- 用
ipmitool sensor list查看各硬件传感器读数,重点是 CPU 温度、系统风扇转速、电源状态。 - 检查机房环境温度,确认空调是否正常工作、机柜风道是否被堵住。
- 如果风扇报错,先看是不是灰尘太多导致转速异常,清理灰尘后一般能恢复。
- 电源模块报警时,优先确认电源线连接和机房供电,双电源机器的另一路电源是否正常。
实操心得:风扇和电源这类硬件告警,很多时候不会立刻让机器宕机,但它是一个强信号。如果带外管理显示某个风扇转速为0,别看机器还在跑就无所谓,这种故障大概率在一周内会变成实际宕机。提前安排停机更换,比半夜被叫起来处理强得多。
3.12 第12种:虚拟化或集群环境中的故障转移异常
现象:虚拟机漂移失败、集群节点心跳丢失、负载均衡后端被健康检查摘掉、共享存储掉线导致服务不可用。
排查路径:
- 先确认物理宿主机和虚拟化平台控制面是否正常,宿主机负载是否过高。
- 检查集群节点之间的心跳网络是否通畅,防火墙是否放行了集群通信端口。
- 查看虚拟化平台的日志,比如 vCenter、Proxmox、OpenStack 的对应日志。
- 如果涉及共享存储,检查存储网络和锁机制,确认没有出现脑裂。
经验之谈:集群环境出问题时,最关键的是“恢复优先于排查”。在脑裂场景下,两个节点同时认为自己是主节点,此时强行干预可能会造成数据损坏。高级做法是先隔离非活跃节点,再由主节点恢复服务,最后慢慢看日志分析原因。新手在集群故障里最容易犯的错,就是一上来乱动多个节点,结果越搞越乱。
4. 一次真实故障排查的完整过程记录
光说不练假把式,我分享一个最近遇到的实战案例。事情的过程是:凌晨两点,监控平台报警,一台运行 MySQL 的服务器 CPU 负载持续走高,数据库查询变慢,部分接口超时。
我的排查步骤是这样的:
- 先通过堡垒机登录服务器,执行
uptime,看到 load average 已经到 30 以上(这台是16核的机器)。 - 执行
top -c发现 mysqld 进程 CPU 占用接近 900%,也就是占了差不多9个核。 - 接着用
mysql -e "show processlist"查看 SQL 情况,发现有大量相同的 SELECT 语句在跑,状态是 Sending data。 - 进一步分析,发现这些 SQL 都在查同一张历史记录表,而这张表的数据量因为某个业务任务扩容,从200万行涨到了8000万行,但索引没有调整。
- 确认没有其他异常后,我先给这张表加了联合索引,然后暂停了那个业务任务,CPU 负载在几分钟内就降下来了。
整个过程大概花了30分钟。复盘下来,真正的问题不是服务器本身,而是应用侧的数据量变化导致了慢查询。这个案例也说明了一个道理:服务器故障的根源往往不只在服务器上,应用对资源的消耗方式才是常态。
5. 故障排查工具与命令速查表
为了方便大家随时查阅,我把文章里涉及的主要命令整理成了一张速查表。下面的内容建议截图保存或者放进自己的运维笔记里。
| 排查场景 | 核心命令 | 关键输出解读 |
|---|---|---|
| CPU 负载 | top -c、uptime | load average 连续高于核数说明有瓶颈 |
| 内存状态 | free -h、dmesg | grep -i oom | OOM 记录显示被杀的进程名 |
| 磁盘空间 | df -h、df -i | inode 100%时文件无法创建 |
| 磁盘 IO | iostat -x 1、iotop | %util 高且 await 高说明盘慢 |
| 网络连通 | ping、mtr、ip addr | 分段判断问题出在哪个链路 |
| 端口监听 | ss -lntp、netstat -tunlp | 确认服务是否正确绑定端口 |
| SSH 日志 | journalctl -u sshd、/var/log/secure | 查看认证失败来源 IP |
| 服务状态 | systemctl status 服务名 | 查看进程死活和启动报错 |
| 服务日志 | journalctl -u 服务名 -n 100 | 查看最近一次崩溃前的日志 |
| 时间同步 | timedatectl、chronyc sources -v | NTP synchronized 状态和时间源是否可达 |
| 硬件传感器 | ipmitool sensor list | 查看风扇、温度、电源等硬件状态 |
| 系统日志总入口 | journalctl -xe | 大部分系统服务异常会记录在这里 |
6. 排查过程中的三个关键心态
分享几个我从实战里悟出来的经验,希望在关键时刻能帮你稳住心态。
第一,先恢复服务,再找根因,这两件事可以有先后顺序。生产环境里服务多挂一分钟,损失就多一分钟。如果确认是某个进程异常,先重启服务恢复可用性,再去看日志分析原因,完全没有问题。不要一上来就想一次定位到底,那是理想情况。
第二,变更记录是排查故障最好的朋友。很多服务器故障不是无缘无故出现的,大概率是最近有人改了什么。安全组规则改了?发布新版本了?定时任务新增了?磁盘快照策略变了?如果你有完整的变更记录,故障排查能少走一半弯路。我强烈建议任何服务器操作都有一个简单的变更记录文档,哪怕是群聊里的 @所有人 通知都行。
第三,报警不一定是故障,但每个报警都值得看一眼。频繁误报会导致人疲劳,等真出问题的时候反而没人响应。科学的做法是完善监控项的阈值,比如磁盘使用率80%告警是提醒,95%告警才是紧急,分级处理,而不是把所有事都当成一样的严重级别。
7. 一份实用的服务器日常巡检清单
最后分享一个我一直在用的每日巡检模板。这套东西不复杂,但能提前发现大部分“还没爆发的故障”。
- 硬件层:检查 RAID 状态是否正常,硬盘灯有没有异常,带外管理有没有告警。
- 系统层:CPU 负载、内存使用率、磁盘空间、inode 使用率、系统日志中是否有新的 error 记录。
- 应用层:核心服务的进程是否在运行、端口是否正常监听、应用日志有没有新的 Exception。
- 网络层:外网连通性、DNS 解析正常性、带宽使用情况、安全组与防火墙规则是否被改动过。
- 备份层:确认今天的备份任务执行成功,并且备份文件可以正常读取。备份不能恢复等于没有备份。
这套巡检用脚本自动化执行,每天出个报告推送到群里,比人肉去看靠谱得多。等哪天真出事了你就会发现,平时养成的小习惯,才是最大的救命稻草。
这次的12种故障和排查方法就先写到这里。下次你遇到服务器报警的时候,别慌,先深呼吸,看看系统日志,看看负载曲线,按这条思路一步步走,问题大概率很快就能浮出水面。