LHIDC

linux高并发下失败,不应只看CPU:负载、IO等待与连接数的测试顺序

面向IT运维工程师,梳理高并发压测失败时CPU、负载、IO等待和连接数的关系,给出先排连接与等待、再判断CPU瓶颈的测试顺序,帮助避免资源误判。

linux高并发下失败,不应只看CPU:负载、IO等待与连接数的测试顺序

一次高并发压测失败后,现场常见的第一反应是打开 top,看到 CPU 使用率上升,就判断“CPU 不够”。这个判断很危险:Linux 服务器高并发下失败,可能是 CPU 计算能力不足,也可能是连接队列被打满、磁盘或网络 IO 等待、应用线程池阻塞、文件描述符耗尽,甚至是压测端先到瓶颈。

更稳妥的前提是:压测端、网络路径、应用日志和系统指标必须放在同一时间窗口观察。只有当连接没有异常堆积、IO 等待不高、应用线程没有大量阻塞,而 CPU 用户态或内核态持续占满时,才适合把问题归到 CPU 资源不足。否则,单看 CPU 很容易把“等待”误判成“算力不够”。

先确认失败是什么,而不是先猜瓶颈

高并发失败不是一个单一现象。不同失败类型对应的排查方向完全不同,压测复盘时应先把故障表现定清楚:

  • 请求超时:可能是应用处理慢、连接排队、下游依赖慢、IO 等待高。
  • 连接被拒绝:可能是监听队列、连接数、端口、文件描述符或服务进程异常。
  • 5xx 错误上升:可能是应用内部异常、反向代理转发失败、后端连接池耗尽。
  • 吞吐不再增加但错误不明显:可能是 CPU、锁竞争、线程池、数据库连接池或压测端到达上限。
  • 延迟陡增但 CPU 不高:应重点看 load average、iowait、D 状态进程和连接队列。

建议在压测记录中保留三个时间点:正常阶段、性能拐点、失败阶段。很多误判都发生在只截取失败后的 top 截图,而没有对比拐点前后的指标变化。

CPU、load average、iowait 与连接数的关系

在 Linux 高并发场景中,这几个指标经常一起出现,但含义不同。

指标 代表含义 常见误判 更可靠的判断方式
CPU 使用率 CPU 时间被用户态、内核态、软中断等消耗的比例 看到 CPU 高就认为要加 CPU 区分 ussysiwa,并结合进程级 CPU
load average 可运行任务和不可中断睡眠任务的平均数量 把 load 直接等同于 CPU 使用率 与 CPU 核心数、D 状态进程、iowait 一起看
iowait CPU 空闲但有任务在等待 IO 完成的时间比例 把 iowait 当成 CPU 忙 结合磁盘延迟、队列、吞吐和阻塞进程判断
连接数 TCP 连接在不同状态下的数量 只看总连接数,不看状态 区分 ESTABSYN_RECVTIME_WAIT、监听队列

load average 尤其容易被误读。它统计的不只是正在 CPU 上运行的任务,也包括不可中断睡眠状态的任务,常见为等待磁盘 IO、部分网络存储、内核资源等。因此,一台多核 Linux 服务器出现高 load,并不必然说明 CPU 算力不足;如果同时 iowait 高、D 状态进程多,瓶颈很可能在 IO 或阻塞链路。

连接数也不能只看总量。ESTAB 多,说明大量连接已建立;SYN_RECV 多,可能是握手或半连接队列压力;TIME_WAIT 多,可能与短连接、主动关闭、端口复用策略有关;监听队列溢出时,用户看到的可能是连接超时或 refused,而不是 CPU 飙高。

采集指标要放在同一时间窗口

排查 Linux 高并发失败,命令不需要一次性堆很多,但必须覆盖系统、进程、IO 和连接状态。以下命令以常见 Linux 发行版为例,部分工具来自 sysstatprocps,如果环境中不存在,需要先按系统版本安装对应软件包。

查看整体负载与 CPU 拆分

uptime
top
mpstat -P ALL 1

观察重点不是某一秒的峰值,而是持续变化:

  • load average 是否持续高于 CPU 核心数较多。
  • %usr 是否高,代表用户态计算压力。
  • %sys 是否高,代表内核态开销明显,可能与网络、文件系统、系统调用有关。
  • %iowait 是否高,说明 CPU 有时间空闲,但任务在等 IO。
  • %soft%irq 是否高,可能与网络包处理、中断压力有关。

如果 top 中 CPU 使用率很高,但 mpstat 显示多个核心并未均衡使用,要继续检查应用是否单进程、单线程、锁竞争或亲和性配置导致单核热点。

查看进程级 CPU、IO 与阻塞

pidstat -u 1
pidstat -d 1
ps -eo pid,ppid,stat,comm,wchan:32 --sort=stat | head -50

pidstat -u 用来确认到底是哪个进程消耗 CPU;pidstat -d 用来看进程级读写;ps 中的 STAT 如果出现大量 D,表示进程处于不可中断睡眠,通常需要进一步看 IO、文件系统、下游依赖或内核等待点。

注意:D 状态不一定等于本地磁盘坏,也可能是网络存储、块设备队列、日志同步、数据库访问、容器存储层等造成的等待。

查看磁盘 IO 等待和队列

iostat -xz 1

排查时重点看:

  • await:请求平均等待时间,持续升高时要警惕。
  • %util:设备繁忙程度,但在多队列设备上不能机械理解为“100% 才满”。
  • r/sw/srkB/swkB/s:判断读写模式是否变化。
  • aqu-sz:平均队列长度,排队明显时会影响应用延迟。

没有基线时,不要仅凭某个字段下结论。更可靠的方式是比较正常阶段和失败阶段:如果并发上升后 iowait、await、队列长度同步上升,而 CPU 用户态并没有打满,优先按 IO 路径排查。

查看 TCP 连接状态和监听队列

ss -s
ss -ant | awk 'NR>1 {state[$1]++} END {for (s in state) print s, state[s]}'
ss -lnt

ss -s 可以快速看 TCP 状态分布。ss -lnt 对服务端很关键,它能看到监听端口的队列情况。对 TCP 监听 socket 来说,输出中的 Recv-QSend-Q 含义与普通连接不同,通常用于观察当前等待 accept 的队列和队列上限。若队列持续接近上限,就要检查应用 accept 能力、反向代理 worker、系统 backlog、连接洪峰以及应用是否被阻塞。

还可以检查文件描述符限制:

ulimit -n
cat /proc/sys/fs/file-nr

如果应用日志中出现 too many open files,连接数上不去就不应优先怀疑 CPU,而应先处理进程级和系统级文件描述符限制,并确认应用是否正确关闭连接。

建议的测试顺序:先排连接和等待,再判断 CPU

高并发压测不是把并发数调大后看哪个指标最高,而是要按顺序缩小瓶颈范围。一个可复用的顺序如下。

1. 确认压测端没有先达到上限

如果压测机自身 CPU、端口、网络、连接数先到瓶颈,服务端指标再漂亮也没有意义。应至少确认压测端:

  • CPU 没有打满。
  • 本机端口没有耗尽。
  • 到服务端的网络没有明显丢包或限速。
  • 压测工具报告的错误类型与服务端日志能对应。

这一点很基础,但在复盘中经常被跳过。尤其是短连接压测,压测端 TIME_WAIT、临时端口范围和连接复用方式都会影响结果。

2. 先看服务端连接是否进入系统和应用

如果请求压不上去,第一步不是看 CPU,而是确认连接有没有正常进入服务端:

ss -s
ss -lnt

判断逻辑可以这样走:

  • SYN_RECV 异常增多:先看握手、半连接队列、网络路径和突发连接。
  • 监听队列持续堆积:应用 accept 或后端处理可能跟不上。
  • ESTAB 增长但应用请求数不增长:可能是应用线程、连接池、代理转发或协议层阻塞。
  • TIME_WAIT 很多:检查是否大量短连接、连接复用是否生效,以及主动关闭方是谁。

连接层异常时,CPU 可能并不高。此时如果直接扩 CPU,往往无法改变失败形态。

3. 再看 load average 是否由 CPU 造成

连接没有明显异常后,再回到负载:

uptime
mpstat -P ALL 1

一个经验判断是:把 load average 与 CPU 逻辑核心数对比,只能作为入口,不能作为最终结论。比如 8 核机器 load 长时间超过 8,说明排队或等待压力明显,但需要继续拆分:

  • us 高、wa 低、运行队列高:更接近 CPU 计算瓶颈。
  • sy 高:可能是内核态开销、网络栈、文件系统、上下文切换等。
  • wa 高:更像 IO 等待导致 load 上升。
  • CPU 空闲仍不少,但 load 高:重点查 D 状态、锁等待、外部依赖或线程池阻塞。

如果业务运行在容器或虚拟化环境,还要注意 cgroup CPU 限额和宿主机调度。容器内看到的核心数、限额和应用实际可用 CPU 可能不一致。

4. iowait 高时要看“谁在等”和“等什么”

iowait 高不代表 CPU 不够,反而说明 CPU 有空闲时间,但任务在等 IO。继续检查:

iostat -xz 1
pidstat -d 1
ps -eo pid,stat,comm,wchan:32 | grep ' D '

常见触发因素包括:

  • 日志同步写入过多,压测时访问日志、错误日志快速增长。
  • 数据库、本地缓存、队列组件读写变重。
  • 临时文件、上传文件、会话文件集中落盘。
  • 容器 overlay 存储层带来额外写放大。
  • 网络存储或远程挂载响应变慢。

这里要避免另一个误判:看到 iowait 高就立即归因于磁盘硬件。正确做法是先定位进程和文件路径,再判断是应用写入策略、日志级别、数据库慢查询、文件系统挂载,还是底层设备能力问题。

5. 最后判断 CPU 是否真是主瓶颈

只有在以下条件同时成立时,CPU 不足的判断才更可靠:

  • 高并发失败阶段,CPU 用户态或内核态持续接近满载。
  • iowait 不高,D 状态进程不多。
  • TCP 连接队列没有明显堆积,文件描述符没有耗尽。
  • 应用日志没有大量下游超时、连接池耗尽或锁等待。
  • 增加并发后吞吐不再增长,延迟上升,CPU 使用率同步上升。
  • 降低并发后 CPU 和延迟能同步恢复。

即使满足这些条件,也应继续定位到具体进程、线程或代码路径。对应用服务而言,CPU 高可能来自业务计算、序列化、压缩、加密、正则、日志格式化、GC、系统调用放大等,不一定是单纯“机器 CPU 不够”。

常见异常组合与优先排查方向

下面这些组合适合作为复盘时的快速判断表,但不能替代现场验证。

现象组合 更可能的方向 下一步检查
CPU 高、iowait 低、load 高 CPU 计算或内核态开销 pidstat -u、应用线程栈、热点接口
CPU 不高、load 高、iowait 高 IO 等待或 D 状态阻塞 iostat -xzpidstat -d、D 状态进程
连接超时、SYN_RECV 握手、队列或网络突发压力 ss -s、监听队列、网络丢包
ESTAB 多但请求处理慢 应用线程池、连接池或下游依赖 应用日志、线程栈、数据库连接池
TIME_WAIT 多且端口压力大 短连接或主动关闭策略 keepalive、压测端端口、连接复用
load 高但 CPU 仍有空闲 等待、锁、IO 或调度限制 D 状态、上下文切换、容器 CPU 限额
5xx 增多但系统指标正常 应用层异常更可疑 Nginx/应用错误日志、上游返回码

这张表的价值在于提醒排查顺序:先根据失败形态分流,再用指标验证,而不是先选一个指标套原因。

影响判断的几个边界条件

采样间隔太粗会掩盖瞬时队列

高并发失败往往发生在几秒内,单次 top 或一分钟级监控可能看不到突发。压测期间建议使用 1 秒级采样观察关键窗口,至少覆盖并发上升、错误出现和恢复三个阶段。

平均值会掩盖单核热点

整体 CPU 只有 50%,不代表没有 CPU 瓶颈。单线程进程、全局锁、单 worker、连接集中到少数进程,都可能造成单核打满。此时要看 mpstat -P ALL 1 和进程线程级指标,而不是只看总 CPU。

应用层队列会让系统指标看起来“正常”

线程池、协程调度、数据库连接池、消息队列消费者不足,都可能让请求在应用内部排队。系统 CPU 不高、IO 不高,但接口延迟持续上升,这时应抓应用线程栈、查看慢日志和连接池等待,而不是继续盯着系统资源。

虚拟化和容器会改变指标解释

容器内看到的 CPU 核心数不一定等于可用配额。虚拟机环境还可能出现 steal time,表示 CPU 时间被宿主机调度占用。排查时应确认:

mpstat 1
cat /sys/fs/cgroup/cpu.max 2>/dev/null

不同发行版和 cgroup 版本路径可能不同,实际检查前需要结合系统版本确认。若存在 CPU quota,应用看到“多核”但实际只能使用部分 CPU,压测结果就会被限制策略影响。

修复或调整后要这样验证

无论最后调整的是应用参数、连接队列、日志策略、数据库连接池,还是 CPU 相关配置,都不要只看错误是否暂时消失。更可靠的验证方式是对比同一压测模型下的指标变化:

  1. 使用相同的压测入口、并发递增方式和请求模型。
  2. 记录正常阶段、拐点阶段、失败阶段的 CPU、load、iowait、连接状态。
  3. 确认失败类型是否改变,例如从连接超时变为应用 5xx,说明瓶颈可能转移。
  4. 检查吞吐、延迟和错误率变化是否与某项资源指标同步。
  5. 保留应用日志、系统指标和压测报告的时间戳,避免跨时间段拼接证据。

如果调整后 CPU 下降,但连接队列仍堆积,说明 CPU 不是唯一问题;如果 iowait 下降后延迟明显恢复,之前的高 load 很可能主要由 IO 等待贡献;如果连接状态正常、iowait 不高、CPU 持续满载且吞吐到顶,才更接近 CPU 瓶颈。

高并发压测的判断边界应始终清楚:CPU、load average、iowait 和连接数不是互相替代的指标。CPU 描述计算时间,load 描述运行与等待压力,iowait 描述 IO 等待占比,连接数描述入口和协议状态。把它们放在同一个时间窗口里按顺序验证,才能避免把 Linux 服务器高并发下失败简单归因于 CPU 不足。

上一篇 日本名古屋云服务器和大阪云服务器面向关西用户,延迟与交付如何比较

LHIDC 产品中心

继续查看可购买的海外服务器产品

文章用于辅助选型,最终价格、库存与配置请以产品详情页和下单页面展示为准。

查看产品 查看方案