凌晨3点,报警群响了。老板问:“服务器怎么挂了?” 开发说:“代码没动过。” 运维说:“资源看着还行啊。”
作为技术人,遇到性能问题最忌讳乱猜。
🚑 01. 全景问诊:系统负载 (top)
先看一眼“生命体征”。输入top,重点看前五行。
💻 终端真实回显
top - 14:28:14 up 100 days, 3:30, 2 users, load average: 5.15, 4.05, 2.50 Tasks: 201 total, 2 running, 199 sleeping, 0 stopped, 0 zombie %Cpu(s): 15.2 us, 5.1 sy, 0.0 ni, 45.5 id, 33.9 wa, 0.0 hi, 0.3 si MiB Mem : 15886.0 total, 2510.5 free, 8213.2 used, 5162.3 buff/cache MiB Swap: 2048.0 total, 2048.0 free, 0.0 used. 7125.0 avail Mem🧐 核心指标解读
**Load Average (平均负载)**:
看哪里:第一行
5.15, 4.05, 2.50(分别代表1、5、15分钟)。诊断:假设这是一台4核服务器,现在负载是5.15,说明有进程在排队,系统超载了。
**%Cpu(s) (CPU状态)**:
**us (user)**:15.2% —— 用户进程消耗,不高。
wa (wait):33.9% —— 警报!这个值高,说明CPU大量时间在等待磁盘I/O。
结论:大概率不是CPU算不过来,而是磁盘太慢拖累了CPU。
🧠 02. 深度分析:CPU排查 (
vmstat)如果
top看不出所以然,或者你想知道更深层的瓶颈,用vmstat。💻 终端真实回显
输入
vmstat 1(每秒刷新一次):procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 6 0 0 251014 120560 516230 0 0 0 40 1205 3452 85 10 5 0 0 7 0 0 250980 120560 516230 0 0 0 0 1340 5102 90 9 1 0 0🧐 核心指标解读
**r (running)**:
数值:6, 7。
诊断:正在运行或等待CPU的进程数。如果你只有4核,但这里长期显示 >4,说明CPU算力严重不足。
**b (blocked)**:
数值:0。
诊断:处于不可中断睡眠(通常在等IO)的进程。如果这里有值,通常伴随着磁盘卡顿。
**us (user)**:
数值:85%, 90%。
诊断:用户态占用极高,这次确实是应用程序(如Java、Python)在疯狂计算。
💾 03. 拒绝误判:内存排查 (
free)新手最容易被“内存使用率”吓到。
💻 终端真实回显
输入
free -h:total used free shared buff/cache available Mem: 15Gi 4.2Gi 2.5Gi 1.0Gi 8.8Gi 10Gi Swap: 2.0Gi 0B 2.0Gi🧐 核心指标解读
**used (已用)**:4.2Gi。
**buff/cache (缓存)**:8.8Gi ——注意!这是Linux为了加速把文件读到了内存里,不是内存泄漏。
available (可用):10Gi——只看这个!
诊断:只要
available还很大,说明内存非常健康。千万不要看到used加上buff/cache快满了就去重启服务。
💿 04. 抓包现行:磁盘I/O (
iostat)刚才在
top里看到wa很高?来实锤一下。💻 终端真实回显
输入
iostat -xz 1:Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm %util await svctm vda 0.00 450.00 0.00 12500.00 0.00 0.00 0.00 0.00 99.5 12.5 2.10 scd0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00🧐 核心指标解读
%util:99.5。
诊断:磁盘已经满负荷运转了(接近100%)。此时任何新的读写请求都会排队,导致系统卡顿。
await:12.5(毫秒)。
诊断:这是IO请求的平均等待时间。如果是SSD,这个值应该在1-2ms以内;如果是机械盘,超过10ms也说明很慢了。
谁在写磁盘?此时可以使用
iotop -o命令,它能像top一样列出是哪个进程(PID)在疯狂读写。📡 05. 现代网络:端口与连接 (
ss)查看端口占用,别再用慢吞吞的
netstat了,现代 Linux 推荐用ss。💻 终端真实回显
输入
ss -lntp(查看监听端口):State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1234,fd=3)) LISTEN 0 100 *:8080 *:* users:(("java",pid=2561,fd=10)) LISTEN 0 50 *:3306 *:* users:(("mysqld",pid=1890,fd=15))🧐 核心指标解读
Recv-Q / Send-Q:
诊断:在
LISTEN状态下,如果Recv-Q(当前全连接队列长度)超过了Send-Q(最大队列长度),说明连接队列满了,新的请求会被拒绝。这通常是并发太高,服务处理不过来了。
Process:
可以直接看到是
java还是mysqld在占端口,以及它们的 PID。
📝 总结:急救小抄
遇到问题不要慌,按这个顺序把脉:
top👉 负载高吗?是 CPU 忙(
us高)还是磁盘忙(wa高)?vmstat 1👉 运行队列
r是否堵塞?free -h👉 别管
used,只看available够不够。iostat -xz 1👉
%util是不是飙到了 100%?
💡 避坑指南:
不要随意执行
echo 3 > /proc/sys/vm/drop_caches清理缓存,这会导致系统为了重建缓存而引发IO风暴,让卡顿雪上加霜。
本文内容经过实战验证,建议转发收藏,以备不时之需!