排查问题常用命令
你现在的核心问题是:系统 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,例如:
| PID | RES | COMMAND |
|---|---|---|
| 8765 | 8.9 GB | java |
| 21416 | 4.5 GB | java |
| 24354 | 3.5 GB | java |
这些很可能是 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 通常由两类进程引起:
- 可运行进程多(CPU 不够)→ 但你 CPU idle 95%,排除
- 不可中断睡眠进程多(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 状态进程列表 发给我,我能立刻告诉你哪个容器该背锅!
