做运维这些年,最怕半夜电话响。十有八九是服务器出问题了,但问题五花八门,有时候连日志都读不出个所以然。今天把常见故障的排查思路整理一下,不讲理论,只讲实战。
一、先看状态,别急着动手
很多新手一看到服务挂了,脑子就热,直接重启。这是最容易踩的坑。我习惯先跑一遍基础状态检查,心里有数再下手:
# 检查系统负载和进程状态
uptime
top -bn1 | head -20
# 查看内存使用
free -h
# 看磁盘空间
df -h
# 检查系统日志的最后几行
tail -50 /var/log/syslog # Debian/Ubuntu
tail -50 /var/log/messages # CentOS/RHEL
这几个命令跑下来,CPU、内存、磁盘、负载情况基本就清楚了。我之前遇到过一次MySQL连接不上,查了半天发现是磁盘满了,binlog 写不进去。
二、网络问题排查:端口和连通性
服务器连不上是最常见的故障之一。排查思路从外到内:
# 检查端口是否在监听
ss -tlnp | grep 80
netstat -tlnp | grep 80
# 外部测试端口连通性(在你的电脑执行)
telnet 服务器IP 80
nc -zv 服务器IP 80
# 看防火墙规则
iptables -L -n
ufw status # Ubuntu
firewall-cmd --list-all # CentOS
# 查看网络连接数(判断是否被攻击)
netstat -an | grep ESTABLISHED | wc -l
netstat -an | grep TIME_WAIT | wc -l
有次客户说网站打不开,ping得通但80端口不通。最后一查是云服务器的安全组没开80入站规则。这种事说实话挺常见的,新手容易忽略云控制台那边的网络策略。
三、进程挂了怎么查
服务进程消失或者崩溃,一般看进程状态和日志:
# 看进程是否存活
ps aux | grep nginx
systemctl status nginx
# 查看OOM Killer日志(内存溢出被内核杀掉)
dmesg | grep -i "out of memory"
dmesg | T | grep "killed process"
# journalctl 看 systemd 日志
journalctl -u nginx --since "10 minutes ago"
journalctl -xe --no-pager
# 查找core dump文件
find / -name "core.*" -type f 2>/dev/null
Java应用特别容易遇到OOM,之前有个项目用了不合理的JVM堆内存配置,生产环境跑了几天就被OOM Killer干掉了。调整了-Xmx参数就好了。
四、日志分析的野路子
有时候日志本身没问题,但架不住量大。以下技巧能快速定位问题:
# 按错误关键字过滤
grep -i "error" /var/log/nginx/access.log | tail -50
# 统计HTTP状态码分布
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
# 找异常的QPS尖峰
awk '{print $4}' access.log | cut -d: -f2 | sort | uniq -c | sort -rn | head -20
# 实时 tail + grep 组合
tail -f access.log | grep -E "(error|500|502)"
学会用awk和grep配合,基本能应付80%的日志分析场景。剩下20%可能需要上Elasticsearch或者Kafka,但那是另一个话题了。
五、常见故障排查清单
总结一下我自己的排查习惯,按顺序来:
- 网络通不通:ping + telnet/nc 先确认基础连通性
- 端口开没开:ss/netstat 看监听状态,安全组也查一下
- 进程活没活:ps + systemctl 看进程状态
- 资源够不够:CPU/内存/磁盘 iostat free
- 日志有什么:dmesg + journalctl + 应用日志
- 最近改了什么:history 看最近命令,回滚配置看能不能恢复
六、写给新手的建议
故障排查没有捷径,但有方法论。我的经验是:
先把问题复现,然后隔离变量,最后逐个排除。不要同时改三四个配置,改完发现好了,也不知道是哪个起作用了。
另外养成好习惯:动任何配置前先备份,改完要记录,改出问题要能回滚。这是血的教训换来的。
服务器出故障不可怕,可怕的是不知道问题在哪。希望这篇文章能帮你在半夜少掉几根头发。
