ps命令

下面给你两部分内容

  1. 对你这份 ps -o pid,tid,stat,wchan:35,pcpu,comm -Lp 25964 输出的分析

  2. ps -o 还能有哪些关键参数(完整清单/推荐组合)


一、你这个输出的分析(重点:性能瓶颈在哪里)

1)绝大多数线程在 futex_wait_queue_me

你输出里绝大部分线程状态是:

Ssl  futex_wait_queue_me

含义是:

  • S:sleep(睡眠)

  • s:可中断 sleep

  • l:有本地锁(lock)

futex_wait_queue_me 是 Linux 内核的 futex 等待队列,通常表示:

  • Java 线程在等待锁(synchronized / ReentrantLock / condition)

  • 或者在等待队列(BlockingQueue.take / Object.wait / CountDownLatch.await)

  • 或者在等待线程池/队列/信号量

结论:
当前 Kafka 进程里大量线程处于“等待锁/等待队列”,并非 CPU 密集型。


2)有少量线程 CPU 高(17%+)

你输出里有一批线程 pcpu 17.6 ~ 18.2

26422 17.6 futex_wait_queue_me
26423 17.6 futex_wait_queue_me
...
26426 18.2 futex_wait_queue_me

虽然也在 futex_wait_queue_me,但 CPU 占用却很高,这说明:

  • 这些线程很可能在 忙等(busy spin) 或者

  • 在不停的尝试获取锁(锁竞争非常激烈)

  • 或者 JVM GC/内部线程在频繁轮询

结论:
你遇到的“性能问题”很可能不是“单线程 CPU 高”,而是 锁竞争/线程大量等待导致系统效率低


3)ep_poll 线程:IO 等待

你有很多线程在 ep_poll

26432 ep_poll 4.9
26433 ep_poll 4.5
...

ep_poll 表示:

  • 网络 IO / socket 事件等待(Kafka 网络层 NIO)

  • 这些线程处于等待状态,但 CPU 仍然有占用,可能是:

    • 大量连接

    • 大量请求

    • 网络负载高

    • 线程池大小过大导致上下文切换


4)Rsl 的线程:Running + sleeping lock

Rsl 表示:

  • R:running(运行中)

  • s:可中断 sleep

  • l:持有本地锁

这类线程可能是:

  • 正在处理请求(但在某个锁上)

  • 或者处于短暂运行状态


二、你的问题核心是什么?

从你这份输出可以推断:

结论:

Kafka 进程当前不是 CPU 饱和型,而是“线程等待/锁竞争/网络 IO”型

你需要进一步确认:

  • 哪些线程是 “真实业务线程”

  • 哪些线程在 futex 上等待的锁是谁持有

  • 是否出现大量线程堆积(线程池配置过大)


三、如何进一步定位(你现在缺少关键点)

ps 只能告诉你线程在等待什么,但不能告诉你具体 Java 线程名、堆栈

要进一步定位,你必须拿到 Java 线程栈

你之前 jstack -F 报错,说明:

  • JVM 可能是 OpenJDK 8u201

  • 或者进程处于某种状态(内存损坏、coredump、容器/权限、seccomp 等)

  • 也可能是 系统与 JVM 版本不匹配jstack 与 JVM 不一致)

你可以用 gcore 生成 core dump,再离线分析。


四、ps -o 关键参数(完整清单/推荐)

ps -o 的字段很多,我把你最常用、最有价值的列出来:


1)线程/进程识别相关

字段含义
pid 进程 PID
tid 线程 ID
ppid 父进程 PID
pgid 进程组 ID
sid session ID
uid 用户 ID
user 用户名
euser 有效用户
gid 组 ID
comm 命令名(可截断)
args 全部命令行
cmd 同 args
command 同 args

2)状态/时间相关

字段含义
stat 线程状态
s 进程状态(同 stat)
etime 运行时间
time CPU 时间
start_time 启动时间
lstart 启动时间(完整格式)
cputime 总 CPU 时间
vsz 虚拟内存
rss 物理内存
pmem 内存占比
pcpu CPU 占比

3)内存/CPU/IO 相关

字段含义
vsz 虚拟内存大小
rss 常驻内存
pmem 内存占比
pcpu CPU 占比
nice nice 值
pri 优先级
c CPU 利用率
%cpu 同 pcpu

4)等待/锁/调度相关(你现在最需要)

字段含义
wchan 线程等待的内核函数
wchan_name 同 wchan
wchan_fmt 同 wchan
cls 调度类
rtprio 实时优先级
policy 调度策略

5)网络/IO/资源相关

字段含义
tty 终端
rss 物理内存
min_flt 次缺页
maj_flt 主缺页
maj_flt 主缺页
maj_flt 主缺页
blkio blkio 统计(部分系统)

五、推荐“最强 ps 输出组合”(你可以直接复制)

1)最强线程性能视图(CPU + wait + mem + args)

ps -eLo pid,tid,stat,pcpu,pmem,wchan:35,etime,time,comm,args --sort=-pcpu | awk '$1==25964' | head -200

2)线程等待函数聚合(找锁热点)

ps -eLo pid,tid,wchan --sort=wchan | awk '$1==25964 {print $3}' | sort | uniq -c | sort -nr | head -50

3)只看 CPU 高的线程

ps -eLo pid,tid,pcpu,stat,wchan:35,comm --sort=-pcpu | awk '$1==25964' | head -50

六、你下一步需要做什么?

你现在的 ps 输出只能说明:线程多、锁/IO 等待多、CPU 占用不是关键

要真正定位问题,必须拿到:

1)Java 线程栈(jstack / jcmd / gcore)

你的 jstack 报错需要解决。

2)Kafka 自身指标(JMX / metrics)

比如:

  • request handler queue size

  • network processor queue size

  • consumer lag

  • GC pause time


如果你愿意,我可以继续帮你

请你补充两点,我就能给出精确的定位步骤:

  1. 你这台机器的 Kafka 版本JVM 参数(特别是 -Xms -Xmx / GC / 线程池)

  2. 你要分析的是什么问题:

    • 线程多导致系统慢?

    • CPU 高?

    • Kafka 消费/生产延迟?

    • GC 频繁?

    • 还是 jstack 报错导致无法定位?

你回复后,我会给你一套“可执行的排查流程 + 命令 + 判断标准”。


1. 线程级别(更全面的 ps / top)

1.1 线程列表(带线程名、CPU、内核等待、内存、运行时间)

ps -eLo pid,tid,comm,stat,wchan:25,pcpu,pmem,etime --sort=-pcpu | awk '$1==14453' | head -200
  • comm:线程名(非常重要)

  • wchan:内核等待函数

  • pcpu:线程 CPU 占用

  • pmem:线程占用内存(通常不敏感,但仍有用)


1.2 top 实时线程视图(最常用)

top -H -p 14453

P(CPU)或 M(内存)排序。


1.3 查看线程等待函数分布(统计)

ps -eLo pid,tid,wchan --sort=wchan | awk '$1==14453' | awk '{print $3}' | sort | uniq -c | sort -nr | head -50

可以看到 Kafka 线程集中在 futex_wait_queue_me / ep_poll 还是其他。


2. CPU 级别(系统/进程/线程)

2.1 pidstat:线程级 CPU 统计(实时)

pidstat -t -p 14453 1 5

输出解释:

  • %usr:用户态 CPU

  • %sys:内核态 CPU

  • %guest:虚拟机

  • CPU:CPU 核心编号


2.2 perf top(实时热点分析,最强)

perf top -p 14453

如果你想看线程热点:

perf top -p 14453 -g

3. IO 级别(磁盘/网络)

3.1 iostat:磁盘 IO 监控(最关键)

iostat -x 1 5

关注:

  • %util(是否接近 100)

  • await(是否高)

  • avgqu-sz(队列长度)


3.2 pidstat IO(进程级 IO 统计)

pidstat -d -p 14453 1 5

3.3 iotop(实时 IO 排名)

iotop -oPa | head -20

4. 网络级别(连接/吞吐/延迟)

4.1 查看 Kafka 端口连接状态

ss -ntlp | grep 9092
ss -s

4.2 查看连接数、状态分布

ss -nt state established '( sport = :9092 )' | wc -l
ss -nt state close-wait '( sport = :9092 )' | wc -l

4.3 查看 socket 队列是否积压

ss -s | grep -E 'tcp:|connections'

5. JVM 层(GC / 堆 / 线程)

5.1 立即输出 JVM 参数(如果 attach 失败可跳过)

jcmd 14453 VM.flags
jcmd 14453 VM.command_line

如果 attach 不行,可以从 Kafka 启动脚本查看。


5.2 GC 日志(如果已开启)

如果你开启了 GC log,可以实时 tail:

tail -200 /path/to/gc.log

建议生产环境开启:

-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/var/log/kafka/gc.log

6. 关键命令:生成堆栈(如果 attach 失败,用 kill -3)

kill -3 14453

然后查看 Kafka 日志输出。
如果 kill -3 没有输出,说明 JVM 处于“内核阻塞”状态。


7. 最强“系统级”诊断:dmesg / vmstat / sar

7.1 系统整体负载

vmstat 1 5

7.2 系统网络/IO 报错

dmesg | tail -100

7.3 资源利用历史(如果安装 sar)

sar -u 1 5
sar -d 1 5

8. 一条命令搞定“更全”的线程信息(推荐)

如果你想一次性列出线程名、CPU、等待函数、以及时间:

ps -eLo pid,tid,comm,stat,wchan:25,pcpu,pmem,etime --sort=-pcpu | awk '$1==14453' | head -200

你现在最需要的输出

为了快速定位问题,请你执行下面三条命令,并把输出贴出来(越多越好):

ps -eLo pid,tid,comm,stat,wchan:25,pcpu,pmem,etime --sort=-pcpu | awk '$1==14453' | head -200
pidstat -t -p 14453 1 5
iostat -x 1 5

wchanps 输出中用于显示 线程当前在内核中等待的函数(wait channel) 的字段。

而你问的 wchan:25 是一种 格式控制写法,用于控制输出宽度。


1. wchan 是什么?

在 Linux 中,每个进程/线程在进入内核等待时,会记录它正在等待的内核函数名,例如:

  • futex_wait_queue_me

  • ep_poll

  • read

  • write

  • fsync

wchan 就是显示这个等待函数名的字段。


2. wchan:25 的含义

ps-o 格式中,字段:宽度 表示 输出字段宽度

所以:

wchan:25

表示:

  • wchan 字段的输出宽度 固定为 25 个字符

  • 如果函数名不足 25 个字符,左对齐并填充空格

  • 如果函数名超过 25 个字符,会被截断(通常不会超过太多)


3. 为什么要用 wchan:25

因为 wchan 字段有时很长,例如:

futex_wait_queue_me
poll_schedule_timeout
ep_poll

为了让表格对齐更整齐,常用 :25:20 来控制宽度。


4. 你可以改成其他宽度

例如:

  • wchan:20(更紧凑)

  • wchan:35(更宽,不容易截断)

示例:

ps -o pid,tid,stat,wchan:35,pcpu,comm -Lp 14453

5. 你如果想要“自动适配宽度”,可以省略宽度

ps -o pid,tid,stat,wchan,pcpu,comm -Lp 14453

但输出可能会变得不整齐。


如果你希望我给你一个“最实用、最整齐、可读性最强”的 ps 命令格式,我可以直接给你一个标准模板。

posted on 2026-01-21 20:10  吃草的青蛙  阅读(0)  评论(0)    收藏  举报

导航