Linux pressure stall information 怎样定位资源等待
来源:17golang原创
时间:2026-11-03 12:37:19 437浏览 收藏
遇到接口延迟突然升高、批处理吞吐下降时,我通常不会先把问题归咎于“CPU 太高”。Linux 的 pressure stall information(PSI)更适合回答另一个问题:有多少任务因为 CPU、内存或 I/O 资源暂时拿不到而在等待。查看 /proc/pressure/cpu、/proc/pressure/memory 和 /proc/pressure/io 后,再把压力趋势与业务日志、负载指标对齐,才能把“系统变慢”缩小为具体资源等待。
定位 PSI 的核心是先区分资源和压力层次,再观察 10 秒、60 秒、300 秒趋势;some表示至少有部分任务在等,full表示所有非空闲任务同时被该资源卡住。PSI 是争用信号,不是单独的根因证明。
先确认 PSI 文件是否真的可读
系统级 PSI 通过 proc 文件系统提供三个资源入口。先只读取文本,不要把目录不存在、权限错误和指标为零混成同一种情况。
# 查看三个系统级 PSI 接口;缺少某个文件时要记录为“接口不可用”,不能当作压力为零
for resource in cpu memory io; do
path="/proc/pressure/${resource}"
if [ -r "$path" ]; then
echo "--- $path ---"
sed -n '1,2p' "$path"
else
echo "不可读:$path"
fi
done
正常输出通常包含 some 和 full 两行,每行有 avg10、avg60、avg300 与 total。这里的“可读”只说明接口能返回数据,不说明业务已经找到根因。

读懂 some、full 和三个时间窗口
some 统计的是至少有一部分任务在该资源上停顿的时间占比;系统仍可能有其他任务在工作。full 则表示所有非空闲任务同时处于该资源停顿状态,这时实际 CPU 周期没有用于有效工作,持续出现通常比单纯的 some 更值得优先处理。
avg10、avg60、avg300 是最近 10 秒、60 秒和 300 秒窗口的百分比趋势,适合区分短时尖峰与持续压力;total 是累计停顿时间,单位为微秒,适合记录一次采样以来是否持续累积等待。读数应该按同一时刻保存,避免只看一个字段。
| 观察点 | 它回答什么 | 不要怎样解读 |
|---|---|---|
| 资源文件 | CPU、内存还是 I/O 更像等待来源 | 不能凭文件名断言具体进程 |
| some | 是否有部分任务被资源拖住 | 不能直接等同于系统已不可用 |
| full | 是否出现所有非空闲任务同时被拖住 | 不能跳过业务和设备层证据 |
| avg10/60/300 | 压力是瞬时、持续还是长周期 | 不能拿不同时间采样直接比较 |
| total | 停顿是否继续累积 | 不能当成百分比或单次延迟 |
把 PSI 指标和业务现象对齐
PSI 的价值在于把“资源紧张”变成可比较的信号,但下一步仍要回到对应资源的证据。例如 memory 的 some 上升,可以与回收、分配失败、工作集变化或容器内存限制一起看;io 压力升高时,再对照设备延迟、队列深度和具体进程;cpu 压力升高时,结合运行队列、线程并发和调度行为判断是计算量增长还是被其他任务争用。
我会固定保存三类信息:采样时间、三个窗口的 PSI 原文、同时间段业务延迟或吞吐。这样能区分“PSI 先升高导致业务变慢”和“业务流量先升高、随后资源压力增加”,避免只截取故障时刻的一行数字。
# 以固定间隔保存原始文本,便于和业务时间线对齐;不修改内核接口内容
stamp=$(date -u +%Y%m%dT%H%M%SZ)
out="/tmp/psi-${stamp}.txt"
for resource in cpu memory io; do
echo "[$resource]" >> "$out"
cat "/proc/pressure/${resource}" >> "$out"
done
echo "采样文件:$out"
用触发器捕获短时压力尖峰
平均值适合趋势,短时尖峰则可以使用 PSI trigger。官方格式是 。例如 some 150000 1000000 表示在任意 1 秒窗口内,部分内存停顿累计达到 150 毫秒时通知。
触发器绑定在打开的 PSI 文件描述符上,程序需要保持该描述符并用 poll()、select() 或 epoll() 等待;描述符关闭后触发器会注销。下面的示例只展示监控关系,不代表文章环境已经执行过。
#include#include #include #include #include int main(void) { // 1 秒窗口内累计 150 毫秒的部分内存停顿才唤醒 const char trigger[] = "some 150000 1000000"; struct pollfd event = {0}; // 使用 O_NONBLOCK,避免注册或读取时把监控线程卡住 event.fd = open("/proc/pressure/memory", O_RDWR | O_NONBLOCK); if (event.fd
内核接受的窗口范围是 500 毫秒到 10 秒,监控更新间隔也因此有上下限;无特权用户创建监视器时,窗口还必须是 2 秒的倍数。阈值不要凭感觉设置,先用平均值和历史样本观察,再让触发器承担告警或降级入口。

下钻到 cgroup 并保留复查边界
如果系统级 PSI 只告诉你“整台机器有等待”,但服务运行在 cgroup v2 中,可以继续看对应 cgroup 目录里的 cpu.pressure、memory.pressure 和 io.pressure。它们与系统级接口使用同样的格式,也可以配置每个 cgroup 的 PSI monitor。
这个下钻动作解决的是归属问题,不是自动给出根因。仍需把 cgroup 的压力时间与服务请求、批任务、容器限制或设备指标对齐。记录以下复查信息,下一次故障才有可比性:
- 读取的是系统级文件还是哪个 cgroup 的 pressure 文件;
- 保存了哪个资源、哪个
some/full行和哪个时间窗口; - 触发器的阈值、窗口、注册时间以及描述符是否保持打开;
- 同时段的业务延迟、吞吐、错误率和资源专属指标。
常见判断误区
只看 CPU 使用率。 CPU 使用率高不等于 CPU pressure 一定高;反过来,任务等待也可能来自内存或 I/O。应先看三类 PSI,再选择对应的专属指标。
看到 full 就直接扩容。 full 表示所有非空闲任务同时停顿的压力状态,确实值得优先关注,但扩容、限流、迁移任务或降低批任务优先级仍要根据业务目标和其他证据决定。
把 avg10 当成单次请求耗时。 avg10 是最近 10 秒的停顿时间占比,不是某条请求的 P99,也不能代替应用级 tracing。
用一次采样下结论。 PSI 的窗口和累计量都需要时间上下文。短时峰值可以用 trigger 捕获,持续问题则应保存多个采样点并与业务时间线对齐。
结语:先用 PSI 找到等待资源,再决定动作
这套方法的落点很简单:先确认 /proc/pressure 是否可读,按资源查看 some/full 和三个窗口,再用同时间的业务证据判断等待是否相关;只有平均值抓不住短峰时才注册 trigger,只有系统级归属不够时才下钻 cgroup。这样 PSI 才是定位链条中的一个可靠观测面,而不是替代日志、追踪和资源专属指标的万能答案。
相关问题
PSI 的 total 为什么不是百分比?
total 是累计停顿时间,单位为微秒;百分比趋势看 avg10、avg60 和 avg300。
some 和 full 应该优先看哪一个?
先同时看两者:some 反映部分任务等待,full 反映所有非空闲任务同时等待。持续 full 通常更严重,但仍要结合资源类型和业务影响。
PSI 能直接指出哪个进程最慢吗?
不能。PSI 描述资源争用造成的停顿,需要结合 cgroup、进程级观测、日志和业务指标继续归因。
-
417 收藏
-
493 收藏
-
257 收藏
-
Golang · Go教程 | 1星期前 | goroutine · HTTP服务 · pprof · Go教程 · Go goroutine泄漏 Go诊断 net/http/pprof goroutine profile pprof.Handler318 收藏
-
240 收藏
-
166 收藏
-
148 收藏
-
432 收藏
-
227 收藏
-
308 收藏
-
383 收藏
-
285 收藏
-
413 收藏
-
247 收藏
-
157 收藏
-
263 收藏
-
391 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习