Skip to content

排查问题常用命令

你现在的核心问题是:系统 load average 很高(5.64),接口响应慢(4~7 秒),但不确定是 哪个容器 导致的。

虽然你怀疑 tudou-procelyt-py,但从之前数据看它的资源使用很低(CPU 1.37%,内存 800MB),不太可能是主因


✅ 正确思路:从全局出发,找出“最可疑”的容器

我们按以下顺序排查:


🔍 第一步:列出所有容器的实时资源消耗(按 CPU + 内存排序)

bash
# 按 CPU 使用率排序(取前 10)
docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.BlockIO}}" | head -11

# 或按内存使用排序
docker stats --no-stream --format "table {{.Name}}\t{{.MemUsage}}\t{{.CPUPerc}}\t{{.BlockIO}}" | sort -k2 -hr | head -15

🎯 重点关注

  • CPU % 持续 > 50% 的容器
  • 内存使用 > 几 GB 的容器
  • BLOCK I/O 读写很高 的容器(如 100MB / 0B

🔍 第二步:结合 top 中的高内存 Java 进程,反查对应容器

你之前的 top 显示多个 Java 进程 RES 超过 3GB~8GB,例如:

PIDRESCOMMAND
87658.9 GBjava
214164.5 GBjava
243543.5 GBjava

这些很可能是 Docker 容器内的进程。我们来反查它们属于哪个容器。

方法:通过 PID 找容器名

bash
# 示例:查 PID 8765 属于哪个容器
PID=8765
CONTAINER_ID=$(cat /proc/$PID/cgroup | grep "docker" | head -1 | sed 's/.*docker\/$[a-z0-9]\{12\}$.*/\1/')
if [ -n "$CONTAINER_ID" ]; then
  docker ps --filter id=$CONTAINER_ID --format "table {{.Names}}\t{{.Image}}"
else
  echo "PID $PID 不在容器中(可能是宿主机进程)"
fi

对每个高内存 Java PID 都执行一次(8765, 21416, 24354, 21316...)。

💡 极大概率这些 Java 进程都来自 不同的业务容器,且总内存占用巨大。


🔍 第三步:检查是否有容器处于“僵尸”或“频繁重启”状态

bash
# 查看所有容器状态(包括退出的)
docker ps -a --format "table {{.Names}}\t{{.Status}}\t{{.Image}}" | grep -E "Exited|Restarting"
  • 如果有容器 不断重启(Restarting),会反复拉起进程,推高 load。
  • 如果有容器 Exited (137) → 被 OOM Killer 杀死(内存不足!)

🔍 第四步:查看系统级 I/O 瓶颈(可能某个容器疯狂读写磁盘)

bash
# 安装 sysstat(如未安装)
yum install -y sysstat || apt-get install -y sysstat

# 查看各设备 I/O 使用率
iostat -x 1 3

关注:

  • %util 接近 100% 的磁盘(如 nvme0n1, sda
  • await(I/O 平均等待时间)> 50ms

然后找出哪个容器在用这块盘:

bash
# 查看容器挂载点
docker inspect <container-name> | grep -A10 -B10 "Source\|Destination"

⚠️ 如果 etcd、MySQL、或某个日志密集型容器和 Java 应用共享同一块高负载磁盘,就会导致全系统卡顿。


🔍 第五步:快速定位“load 高”的直接原因

Load high 通常由两类进程引起:

  1. 可运行进程多(CPU 不够)→ 但你 CPU idle 95%,排除
  2. 不可中断睡眠进程多(D 状态) → 通常是 I/O 阻塞

检查是否有大量 D 状态进程:

bash
# 统计 D 状态进程数
ps aux | awk '$8 ~ /^D/ { count++ } END { print "D-state processes:", count+0 }'

# 列出它们
ps aux | awk '$8 ~ /^D/ { print $0 }'

如果输出很多,说明有进程 卡在磁盘 I/O(比如某个容器在写日志、刷数据)。

再通过 PID 反查容器(同第二步方法)。


🚨 最可能的真相(基于你所有数据)

线索推断
多个 Java 进程 RES 总和 > 50GB大量容器运行 Java 服务
系统无 swap内存压力无法缓冲
load average = 5.64,但 CPU idle 95%进程在 等待内存或 I/O
tudou-procelyt-py 资源使用低不是主因
最可疑对象那些 RES 3~8GB 的 Java 容器

✅ 建议立即执行的命令(复制粘贴)

bash
# 1. 找出 top 10 资源消耗容器
docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.BlockIO}}" | head -11

# 2. 检查 D 状态进程
ps aux | awk '$8 ~ /^D/ { print "D-state PID:", $2, "CMD:", $11 }'

# 3. 对高内存 Java PID 反查容器(以 8765 为例)
PID=8765
CID=$(cat /proc/$PID/cgroup 2>/dev/null | grep -o 'docker/[a-z0-9]*' | head -1 | cut -d/ -f2)
if [ -n "$CID" ]; then
  echo "PID $PID belongs to container:"
  docker ps --filter id=$CID --format "table {{.Names}}\t{{.Image}}"
else
  echo "PID $PID is not in a container"
fi

# 4. 检查磁盘 I/O
iostat -x 1 2

📌 总结

不要只盯着 tudou-procelyt-py
真正的“罪魁祸首”极可能是 某个或多个高内存 Java 容器,它们:

  • 耗尽内存,导致系统频繁回收 page cache
  • 触发 GC 或内存分配阻塞
  • 推高 load average
  • 间接拖慢了所有服务(包括你的 Python 接口)

请运行上面的命令,把 docker stats 前 10 行D 状态进程列表 发给我,我能立刻告诉你哪个容器该背锅!

Released under the MIT License.