- 摩杰斯
- 2026-10-29
Linux 服务器慢怎么排查?先分清六种「慢」,再加配置
在 Linux 服务器上,运维接到"服务器慢"的报障,直接动手查是错的。原因很简单:这句话里没有可以查的东西。
"慢"至少要先补三句:谁觉得慢、慢在哪一段、什么条件下慢。补完这三句,多数情况能直接跳到某一两种形态上,而不是从"加内存"开始一个个试。
这篇把六种"慢"分开讲:各自的信号、怎么拿证据、处置方向,以及最常见的误判。六种形态里,只有第一种是 CPU 真的在算,其余五种都不该用"加配置"来解决。
![]()
一、先把"慢"拆成三句
第一句,谁觉得慢。是操作的人在浏览器里点一下要等三秒?是批量导出报表跑了半小时?是每天八点半全厂同时开工单时卡?三种"慢"完全不是一个问题。前端交互慢,可能一秒都不在服务器上——浏览器渲染、图片加载、接口串行都算在里面。
第二句,慢在哪一段。一次请求在 Linux 上至少经过四段:浏览器与网络、Web 服务与应用代码、数据库、磁盘。定不到段,后面所有动作都是猜。
第三句,什么条件下慢。一直慢、高峰慢、特定操作慢、跑一阵突然慢然后自己好——"时间形状"不同,指向的原因几乎不重叠。这一条最容易被忽略,但它往往一步就能把范围砍掉一半。
二、形态一:CPU 真的在算
信号:top 里 %us(用户态)高,load average 明显超过核数,%wa 很低。
意味着:有东西在实打实消耗 CPU 周期。常见来源是计算密集型任务(导出、统计、图片处理)、死循环或正则回溯、加密与压缩、序列化大对象,以及最近上线的新代码。
top -H -p <pid> # 看哪个线程在吃 CPU
perf top -p <pid> # 看热点函数(有符号时)
pidstat -u 1 5 # 按进程采样,确认是不是它一直在吃
处置方向:先看是不是"该忙"。批量任务在跑、报表在导,那叫正常负载,优化方向是错峰或限流;如果没有任何业务动作却持续满载,才是异常,往死循环、正则回溯、缓存击穿方向查。
最常见的误判:只看 load average。单核机器 load 2 已经过载,32 核机器 load 8 还很闲。load 必须和核数一起看,而且 load 包含等待 IO 的进程,它高不一定是 CPU 忙。
三、形态二:CPU 没忙,在等磁盘
信号:%wa(iowait)持续偏高,%us 不高,load average 也高。机器看起来"忙",但 CPU 大量时间在空转等待。
vmstat 1 5 # 看 wa 列
iostat -x 1 5 # 看每块盘的 await、r/s、w/s、%util
iotop -o # 看哪个进程在读写
一个容易忽略的关联:海量小文件会让 IO 明显变慢。目录里堆了几十万个文件时,读一个文件的元信息都可能触发多次寻址,iostat 上表现为大量小 IO、await 升高。这类"慢"的根因在文件数量,不在磁盘性能——清理文件数量比换更快的盘有效得多。
处置方向:先分清是"读多"还是"写多"、是顺序还是随机。日志同步写、数据库频繁 fsync、备份任务与业务抢 IO,是三个高发场景。备份要限速、错峰;日志要异步或调低刷盘频率(前提是能接受少量丢失)。
四、形态三:内存不够,开始换页
信号:vmstat 的 si/so 不为零(有实际换入换出),free 的 available 很低,dmesg 里出现 OOM 记录。
一旦开始换页,延迟不是"慢一点",是数量级的恶化——一次换页把微秒级的内存访问变成毫秒级的磁盘访问。
free -m # 看 available,不是看 free
vmstat 1 5 # si/so 是否持续非零
dmesg | grep -i oom # 有没有进程被 OOM killer 干掉
最常见的误判:把 buff/cache 当成"被占用的内存"。Linux 会主动用空闲内存做文件缓存,需要时回收,free 一列很低是正常的。判据是 available,它才是"还能给新进程用多少"。
处置方向:先找谁在涨(ps aux --sort=-rss),再看是缓存无上限、连接池过大,还是业务量真的涨了。加内存能缓解,但如果根因是内存泄漏或缓存无上限,加多少都会被吃满。
五、形态四:磁盘本身慢,或者配额用完了
信号:iostat 里 await(平均等待)明显偏高、%util 接近 100,但 CPU 和内存都不紧张。
云上尤其常见一个隐形原因——云盘的 IOPS 与带宽按规格给,突发额度用完之后掉回基线。表现是"上午很快,下午突然变慢,第二天又好了",看起来像玄学,实际是配额。
iostat -x 1 5
# 关注 r_await / w_await 是否几十毫秒以上;%util 是否长期贴 100
关于 %util 的提醒:这个指标在 SSD、NVMe 和多队列设备上会骗人——单块盘 %util 100% 不等于带宽打满,它只是"设备队列非空的时间比例"。看吞吐和 await 比看 %util 可靠。
处置方向:先确认是不是规格/配额问题(云控制台的监控曲线能直接看到上限),再确认是不是写放大(小随机写、日志刷盘过频、数据库页大小与块大小不匹配)。前者升规格或拆分,后者调参数或改写入模式——两种病,两种药。
六、形态五:不是慢,是在排队
信号:CPU 不高、IO 不高、内存够,但请求就是慢;同时数据库或应用里能看到大量等待。
资源都够,但请求在等锁、等连接、等线程。"慢"真正的含义是"排在前面的还没处理完"。三个高发排队点:
数据库锁等待——长事务占着行锁,后面的全堵住。MySQL 看 information_schema.innodb_trx 与 SHOW ENGINE INNODB STATUS 的锁等待段;PostgreSQL 看 pg_stat_activity 里 wait_event_type = 'Lock' 的会话,pg_blocking_pids() 能直接找出阻塞者。
连接池打满——应用侧的最大连接数是硬上限,打满之后新请求排队等连接。表现是接口耗时稳定在一个"奇怪的量级"(比如刚好 3 秒、5 秒),因为那是连接池的等待超时。
应用线程池串行——一个耗时接口占满工作线程,其他请求全排队。日志里会看到大量请求"同时开始、同时结束"。
处置方向:找"最长的那笔事务"或"占着连接不放的那个请求",而不是加机器。加机器对锁等待几乎无效——锁在同一个数据库实例上。
七、形态六:链路与上游
信号:服务器自身指标全绿,但用户端慢;或者服务器出网请求慢。问题在服务器之外。
带宽打满——出网带宽被备份、日志外传、大文件下载占满,iftop 一眼能看出。丢包与重传——ping 看不出问题但 TCP 重传率高,用 ss -s 或 netstat -s | grep -i retrans。DNS 解析慢——每次外部请求都带一次 DNS 超时,累积起来很可观。TLS 握手开销——短连接每次新建握手,RTT 高的链路上代价翻倍。上游依赖慢——第三方接口或内部另一个服务慢,把整条链路拖住,这类最容易误判成"我们服务器慢"。
处置方向:给每个外部依赖加耗时打点,把"我们的耗时"和"等待别人的耗时"分开记。没有这层拆分,永远在猜。
八、一张判据表
| 形态 | 一眼信号 | 第一条命令 | 典型误判 |
|---|---|---|---|
| CPU 真忙 | %us 高、%wa 低 | top / pidstat -u 1 | 只看 load 不看核数 |
| 等磁盘 | %wa 高、%us 低 | vmstat 1 / iostat -x 1 | 直接换更快的盘 |
| 内存换页 | si/so 非零、available 低 | free -m / vmstat 1 | 把 cache 当占用 |
| 磁盘/配额 | await 高、%util 贴顶 | iostat -x 1 / 云监控 | 把 %util 当带宽 |
| 排队 | 资源都闲、请求慢 | 锁等待视图、连接池指标 | 加机器 |
| 链路/上游 | 本机全绿、用户慢 | iftop / ss -s / 依赖打点 | 把等待当自身问题 |
表的用法:先按"哪个资源紧张"分流,再看"紧张的是不是真凶"。注意"资源都闲但请求慢"这一格,它最容易把人带向加配置,实际大多是排队。
九、慢的时间形状,比瞬时数值更有信息量
一直慢:从上线就慢,多半是设计问题——N+1 查询、缺索引、串行调用、单线程处理。加资源只能缓解一时。
高峰慢:早上八点半、每月一号、定时任务时段。这是容量与错峰问题:要么限流排队,要么把批量任务挪开。
爬坡式变慢:一天比一天慢,重启就好——典型的内存泄漏、连接未释放、临时文件堆积、表数据量增长导致索引失效。
突然慢又自己好:云盘突发额度、备份任务、邻居噪音、上游抖动。这类要的是"能对上时间点"的证据,不是调参。
特定操作慢:只在这个报表、这批数据慢。往那条具体路径上查,别在整机上找。
问一句"是哪种形状",往往比看十个监控图有效。
十、五个常见误判
一,直接加内存。内存曲线高不等于内存不够,available 才是判据。加内存对锁等待、慢查询、带宽打满完全无效,却最常被当成第一反应。
二,直接换更强的机器。排队类问题换机器通常无效(锁在同一个库、连接池在上游);设计类问题换机器只是把慢从 3 秒变 2 秒。
三,用 load average 判断负载。它混了 CPU 与 IO 等待,且必须与核数对照。
四,把 %util 当磁盘性能上限。多队列设备上它会误报,看 await 与吞吐更可靠。
五,先调内核参数。sysctl 里那些网络与内存参数,绝大多数场景下不是瓶颈;没定位就调,是把问题变成"调过之后不知道原来是什么问题"。
十一、处置顺序:先止血,再优化,最后防复发
第一层,止血。目标只有一个:让业务先恢复可用。手段通常是限流、降级、错峰、临时扩容、关掉非核心的批量任务。这一步不追求找到根因。
第二层,优化。有了止血争取的时间,再按判据表定位。优化之前先做一件事:留一份基线。当前的 QPS、P95 延迟、各资源水位、慢查询 Top 10 存下来。没有基线,优化完只能说"感觉快了",下次再慢也无法判断是退步还是新问题。
第三层,防复发。把这次出问题的那个信号做成告警。慢类故障最大的特点是可以提前看见——CPU 爬升、内存爬坡、磁盘 await 上升、慢查询数量增长,都早于用户报障。缺的往往不是数据,是"没人看"。
不需要一上来就上全套监控。先有四项就够:负载与 CPU 分布、available 内存与 swap 活动、每块盘的 await、关键接口的 P95。这四项能覆盖绝大多数"慢"的分流,等有了具体问题再补细节指标。这套基础观测我们摩杰斯在交付环境搭建时会一并做掉,原因是它决定了后面每一次"慢"是能查清楚,还是只能猜。




