1. 系统性能下降的排查思路:从现象到根因
当系统突然变慢变卡时,我通常会按照"先整体后局部、先表象后深层"的思路进行排查。这个过程就像医生诊断病情——先观察症状,再检查各项指标,最后锁定病因。以下是经过多年实战总结的标准排查流程:
重要提示:性能问题排查切忌盲目操作,一定要先收集足够的信息再下结论。我曾见过有人一遇到系统卡顿就重启服务器,结果把关键日志也清除了,导致问题永远无法定位。
1.1 症状观察与基础信息收集
首先需要明确"系统变慢"的具体表现:
- 是整体变慢还是特定功能变慢?
- 响应时间变长还是吞吐量下降?
- 是否有错误提示或异常日志?
- 用户感知的延迟发生在哪个环节?
同时立即收集以下基础信息(这些数据对后期分析至关重要):
bash复制# 系统基础状态
top -n 1 -b > system_status.log # 记录当前进程状态
vmstat 1 5 > vmstat.log # 记录系统资源使用情况
dmesg -T > dmesg.log # 检查内核日志
sar -u -r -n DEV 1 5 > sar.log # 系统活动报告
# 如果是Web服务
curl -o /dev/null -s -w \
"time_namelookup: %{time_namelookup}\ntime_connect: %{time_connect}\n...
1.2 资源瓶颈快速定位
通过以下命令可以快速判断四大基础资源瓶颈:
bash复制# CPU瓶颈检查(us过高说明应用计算量大,sy过高说明系统调用频繁)
mpstat -P ALL 1
# 内存瓶颈检查(关注swap使用和OOM日志)
free -h
grep -i oom /var/log/messages
# IO瓶颈检查(await过高说明磁盘压力大)
iostat -x 1
# 网络瓶颈检查(关注retrans和drop)
sar -n EDEV 1 3
我曾遇到过一个典型案例:某电商系统大促时突然变慢,通过iostat发现磁盘await高达500ms(正常应<20ms),进一步排查发现是日志配置错误导致每秒写入10GB调试日志。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 深入分析:分层排查法
2.1 应用层排查
应用代码问题是最常见的性能杀手:
bash复制# 查看慢查询(MySQL为例)
pt-query-digest /var/log/mysql-slow.log
# JVM应用检查
jstack <pid> > thread_dump.log # 线程转储
jstat -gcutil <pid> 1000 5 # GC情况
常见问题包括:
- 死锁或线程阻塞(通过thread dump分析)
- 内存泄漏(通过heap dump分析)
- SQL查询未走索引(需要EXPLAIN分析)
2.2 中间件层排查
中间件配置不当经常导致性能问题:
bash复制# Nginx连接状态
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
# Redis延迟检测
redis-cli --latency -h 127.0.0.1
特别要注意:
- 连接池耗尽(报错"Timeout waiting for connection")
- 缓存击穿(大量请求直接打到数据库)
- 消息队列积压(消费者处理能力不足)
2.3 系统层深入分析
当常规检查无法定位问题时,需要更底层的工具:
bash复制# 系统调用跟踪(查看哪些调用耗时)
strace -p <pid> -c -T
# 性能剖析(需要perf工具)
perf record -F 99 -p <pid> -g -- sleep 30
perf report
我曾用perf发现一个加密库的随机数生成函数消耗了40%的CPU时间,原来是/dev/random阻塞导致。
3. 特殊场景排查策略
3.1 间歇性性能下降
这类问题最难排查,需要:
- 部署长期监控(如Prometheus+Grafana)
- 设置告警阈值(如CPU>80%持续5分钟)
- 保留历史数据(至少7天)
经验分享:对于偶发问题,我会在复现时立即用tmux同步开多个监控窗口:
bash复制tmux new-session 'htop' \; split-window -v 'iftop' \; split-window -h 'iostat -x 1'
3.2 分布式系统排查
分布式系统需要额外关注:
- 网络分区(检查节点间连通性)
- 时钟不同步(ntpdate -q检查时间差)
- 数据一致性(检查副本lag)
建议工具:
bash复制# 跨节点追踪(需要提前部署)
ssh node1 "tcpdump -i eth0 -w /tmp/node1.pcap" &
ssh node2 "tcpdump -i eth0 -w /tmp/node2.pcap" &
4. 性能优化实战案例库
4.1 数据库连接池泄漏
现象:系统运行几天后越来越慢,重启后恢复。
排查过程:
- netstat发现ESTABLISHED连接数异常高
- 通过lsof定位到是Java应用
- jstack发现大量连接未关闭
- 检查代码发现try-with-resources用法错误
4.2 内存泄漏导致频繁GC
现象:每10分钟出现1秒卡顿。
排查过程:
- jstat发现Full GC频繁
- jmap生成heap dump
- MAT分析发现某个缓存未设上限
- 改用Guava Cache并设置maxSize
4.3 日志同步阻塞主线程
现象:高峰期响应时间波动大。
排查过程:
- strace发现大量write系统调用
- 发现是同步写日志到NFS
- 改为异步日志并本地缓冲
- 响应时间P99从2s降到200ms
5. 构建性能防护体系
预防胜于治疗,我通常会建立四道防线:
5.1 监控告警系统
- 基础资源监控(CPU/Memory/IO)
- 应用指标监控(QPS/延迟/错误率)
- 业务指标监控(订单量/支付成功率)
5.2 压测与容量规划
- 定期全链路压测
- 建立性能基线
- 制定扩容阈值(如CPU>60%持续10分钟)
5.3 灰度与熔断机制
- 新功能先灰度发布
- 配置合理的熔断策略
- 实现优雅降级方案
5.4 应急预案
- 准备回滚方案
- 制定问题升级流程
- 关键人员oncall机制
在实际工作中,我发现90%的性能问题都能通过系统化的监控和预案避免。最近一次大促前,我们通过压测提前发现了Redis连接池配置问题,避免了可能的上百万损失。
