服务器故障排查实战:我是怎么一步步找到问题根因的
做IDC运维久了,什么奇葩故障都见过。服务器不通、负载飘高、进程莫名消失……每个故障看起来都不一样,但排查思路其实有套路。今天把我在实际工作中常用的排查流程整理出来,分享给刚入门或者被故障折磨得焦头烂额的朋友。
一、先问自己三个问题
故障来了别急着上手,先快速确认三个事实:
- 问题是什么? 网站打不开,还是SSH连不上,还是某个服务响应慢?
- 什么时候开始? 昨天还正常,今天突然挂了,还是最近逐渐变差的?
- 谁动了什么? 最近有没有改配置、升级系统、上新业务?
这三个问题的答案基本能帮你锁定方向。我遇到的大多数故障,回顾这三个点就能快速缩小范围。
二、网络不通?先从底层ping起
SSH连不上服务器是最常见的情况。很多人第一反应是服务器挂了,其实大部分时候只是网络层面的问题。
第一步:本地网络检查
# 检查本地网络是否正常
ping -c 4 8.8.8.8
# 如果能ping通8.8.8.8但无法访问目标域名
ping -c 4 your-server-ip
# 用traceroute看路由在哪一跳断了
traceroute -n your-server-ip
如果本地ping不通,最可能是本机网络或防火墙的问题,不是服务器的问题。
第二步:端口检测
服务器IP能ping通但端口不通,这时候用telnet或nc:
# 检查22端口是否开放
telnet your-server-ip 22
# 或者用nc(更简单)
nc -zv your-server-ip 22
# 批量检查常用端口
for port in 22 80 443 3306 6379; do
nc -zv your-server-ip $port 2>&1 | grep -E "succeeded|failed"
done
端口不通最常见的原因是:防火墙没开放、iptables规则拦截、服务没启动。
第三步:查看服务器端口监听
如果你是服务器管理员,登录后查看:
# 看哪些端口在监听
netstat -tlnp | grep LISTEN
# 或者用ss(更现代)
ss -tlnp
# 确认服务进程是否在跑
ps aux | grep nginx
systemctl status nginx
有个坑很多人踩过:服务明明在本地127.0.0.1上监听了,但外部无法访问。这时候要改成监听0.0.0.0才行。
三、负载高?先找到元凶进程
服务器CPU飘高或者负载异常,第一件事是找到是哪个进程干的。
第一步:看谁在最耗CPU
# 实时看进程占用(按CPU排序)
top -c
# 或者用htop(更直观)
htop
# 一次性输出,看谁CPU占用超过100%的
ps aux --sort=-%cpu | head -10
第二步:定位线程
# 找到高CPU进程的PID后,查看它的线程
top -Hp <PID>
# 看这个进程打开的文件
lsof -p <PID>
# 看它的网络连接
netstat -anp | grep <PID>
有时候一个PHP脚本死循环,或者MySQL查询没优化,都会把CPU打满。找到进程名就好办了。
第三步:看日志
# Nginx错误日志
tail -n 50 /var/log/nginx/error.log
# PHP-FPM慢日志(如果配了)
tail -n 50 /var/log/php-fpm/slow.log
# 系统日志
journalctl -xe --no-pager
日志里经常藏着直接的答案,比如"too many connections"或者"segmentation fault"。
四、磁盘满了?快速定位大文件
磁盘满了导致服务崩溃,这个太常见了。排查其实很快:
# 看整体使用情况
df -h
# 定位哪个目录占用最多
du -sh /*
# 找到大于100MB的大文件
find / -type f -size +100M -exec ls -lh {} \;
常见的坑:日志文件没做切割、MySQL的binlog占了几十GB、临时文件堆积。找到之后直接清理就行:
# 清理7天前的日志
find /var/log -name "*.log" -mtime +7 -exec rm -f {} \;
# 清理旧的yum缓存
yum clean all
五、服务挂了?先看状态再重启
服务挂了别一上来就重启,先看状态和日志:
# 查看服务状态
systemctl status nginx
# 看是否是systemd管理的
systemctl list-failed
# 查看服务启动失败的原因
journalctl -u nginx --no-pager -n 50
有时候服务被OOM Killer杀掉了,这时候dmesg能看到线索:
dmesg | grep -i "kill\|oom"
如果是内存不足导致的,服务器会把占用内存最多的进程杀掉来释放内存,这就是OOM Killer。
六、常用诊断命令速查
把常用的命令整理成一个小清单,方便快速调用:
# 查CPU/内存
free -m && top -bn1 | head -5
# 查网络连接状态
netstat -an | awk '/^tcp/ {s[$NF]++} END {for(k in s) print k, s[k]}'
# 查进程树
pstree -ap
# 查最近的重启记录
last reboot
# 查历史命令(谁在搞事)
history && last
七、预防大于排查
故障排查得多了,就知道很多问题其实可以预防:
- 监控要到位:CPU、内存、磁盘、端口监控,一个不能少。早点报警能避免很多故障。
- 日志要轮转:logrotate配好,别让日志把磁盘撑爆。
- 变更要记录:改了配置顺手记下来,回滚的时候能救命。
- 备份要定期:数据丢了才是真的灾难。
总结
故障排查没有捷径,但有套路。先问三个问题确认范围,再按网络→进程→日志的顺序排查,大多数问题能在10分钟内定位到根因。关键是心态要稳,别被故障带着走,一步一步来就行。
如果这篇文章对你有帮助,欢迎留言说说你在排查故障时遇到过哪些奇葩问题,我们一起交流。
