15.11.4 资源瓶颈与性能问题定位
资源瓶颈与性能问题定位#
本节聚焦容器在生产环境中的性能劣化与资源瓶颈定位方法,覆盖 CPU、内存、磁盘 I/O 与网络四类关键资源,并提供可执行的诊断与排错步骤、示例命令与练习。
1. 原理与定位流程(含草图)#
容器资源由 cgroup 进行隔离与限制,性能问题需从宿主机→容器→进程逐层收敛。
定位流程(可执行清单)
1. 宿主机是否资源耗尽(CPU/内存/磁盘/网络)
2. 容器是否受限(cgroup 配额)
3. 进程是否异常(高占用、泄漏、阻塞)
4. 变更与流量是否异常(部署/发布/流量峰值)
2. 工具安装与基础准备#
常用性能诊断工具安装(不同发行版请按实际调整):
# Ubuntu/Debian
apt-get update
apt-get install -y sysstat htop iotop iftop iproute2
# CentOS/RHEL
yum install -y sysstat htop iotop iftop iproute
systemctl enable --now sysstat
验证命令是否可用:
iostat -x 1 1
pidstat -u 1 1
3. CPU 瓶颈定位(示例与排错)#
现象:CPU 高、负载升高、响应变慢
关键命令与说明:
# 容器 CPU 使用率与限制
docker stats --no-stream
# 宿主机进程 CPU 排序
top -o %CPU
# 进程级 CPU 使用情况(PID 为容器主进程)
pidstat -u -p <pid> 1 5
# cgroup CPU 配额与周期
cat /sys/fs/cgroup/cpu/docker/<container_id>/cpu.cfs_quota_us
cat /sys/fs/cgroup/cpu/docker/<container_id>/cpu.cfs_period_us
示例:定位 CPU 限制过低
# 查看容器限制
docker inspect -f '{{.HostConfig.NanoCpus}}' app1
# 发现 NanoCpus=500000000(0.5核)
# 调整为 2 核
docker update --cpus=2 app1
常见排错点
- 容器 --cpus 过低导致抢占
- 线程池/并发配置过小
- 应用死循环/热点线程
4. 内存瓶颈定位(示例与排错)#
现象:OOM、重启、延迟抖动
关键命令与说明:
# 容器内存使用与限制
docker stats --no-stream
# 宿主机内存与交换使用
free -m
vmstat 1 5
# OOM 记录
dmesg | grep -i "oom\|killed process"
示例:发现内存限制过低导致 OOM
# 查看容器内存限制
docker inspect -f '{{.HostConfig.Memory}}' app1
# 将内存限制提升到 2G
docker update --memory=2g app1
JVM 示例(若应用为 Java)
# JVM 推荐设置与容器限制匹配
JAVA_OPTS="-Xms1024m -Xmx1024m -XX:+UseG1GC"
常见排错点
- 内存泄漏或缓存未清理
- JVM 堆设置超过容器限制
- swap 配置不合理导致抖动
5. 磁盘 I/O 瓶颈定位(示例与排错)#
现象:写入延迟、启动慢、日志卡顿
关键命令与说明:
# I/O 延迟、队列深度
iostat -x 1 3
# 进程 I/O
iotop -o
# 磁盘空间
df -h
示例:定位日志导致 I/O 突增
# 查看容器日志大小
du -sh /var/lib/docker/containers/<id>/*-json.log
# 配置日志轮转(/etc/docker/daemon.json)
cat > /etc/docker/daemon.json <<'EOF'
{
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "5"
}
}
EOF
systemctl restart docker
常见排错点
- 日志暴涨导致 I/O 饱和
- 数据卷与系统盘共享,争用严重
- 存储 IO 性能不足(随机写放大)
6. 网络瓶颈定位(示例与排错)#
现象:连接超时、丢包、吞吐下降
关键命令与说明:
# 连接状态与队列
ss -s
ss -ant | head
# 实时流量
iftop -i eth0
# 抓包定位重传/超时
tcpdump -i eth0 -nn port 8080 -c 50
示例:定位连接数耗尽
# 查看 TIME_WAIT 占比
ss -ant | awk '{print $1}' | sort | uniq -c | sort -nr
# 临时优化(谨慎使用)
sysctl -w net.ipv4.tcp_tw_reuse=1
常见排错点
- 端口耗尽/连接数过多
- MTU 不一致导致丢包
- NAT 表耗尽
7. 容器资源限制配置示例(完整可执行)#
# 创建容器并限制 CPU、内存与 I/O
docker run -d --name app1 \
--cpus=2 \
--memory=1g \
--memory-reservation=512m \
--blkio-weight=500 \
-p 8080:8080 \
nginx:1.25
预期效果
- CPU 限制为 2 核
- 内存上限 1G,软限制 512M
- I/O 权重低于默认值
8. 典型问题速查与处理#
- 高 CPU + 低吞吐:检查线程池、锁竞争、CPU 限制过低
- 内存持续增长:排查泄漏与缓存,检查 JVM 堆设置
- 磁盘延迟高:日志爆发、磁盘满、I/O 队列深
- 网络延迟高:连接数暴增、MTU 不一致、丢包
9. 练习与实操#
-
CPU 练习
创建 CPU 限制为 0.2 核的容器,观察docker stats与pidstat,再调整为 1 核并比较响应时间。 -
内存练习
用--memory=256m启动容器,运行内存压力工具(如stress),观察 OOM 记录并调整限制。 -
I/O 练习
在容器内持续写入日志,观察iostat -x与iotop,配置日志轮转后验证写入延迟变化。 -
网络练习
使用ab或wrk压测容器服务,观察ss -s中连接状态变化,并抓包验证重传情况。