- 工信部备案号 滇ICP备05000110号-1
- 滇公网安备53011102001527号
- 增值电信业务经营许可证 B1.B2-20181647、滇B1.B2-20190004
- 云南互联网协会理事单位
- 安全联盟认证网站身份V标记
- 域名注册服务机构许可:滇D3-20230001
- 代理域名注册服务机构:新网数码
- CN域名投诉举报处理平台:电话:010-58813000、邮箱:service@cnnic.cn
生产环境中,经常会遇到这样的告警:
Docker Host 内存使用率达到95%
容器没有重启,但内存持续上涨
业务响应越来越慢
很多运维人员第一反应就是重启容器,但如果没有找到真正原因,问题很快又会再次出现。下面介绍一套生产环境常用的排查方法。
首先查看宿主机内存:
free -h
例如:
total used free shared buff/cache
Mem: 32Gi 28Gi 1.2Gi 256Mi 2.8Gi
然后查看所有容器资源使用情况:
docker stats --no-stream
输出:
CONTAINER ID NAME MEM USAGE / LIMIT
f8b6d8d8f2a1 nginx 45Mi / 1Gi
9a74c6a7de32 redis 520Mi / 2Gi
31c97a34d621 java-api 9.6Gi / 10Gi
很容易发现哪个容器占用了大量内存。
进入容器:
docker exec -it java-api bash
如果没有 bash:
docker exec -it java-api sh
查看内存占用:
ps -eo pid,comm,%mem,%cpu --sort=-%mem | head
例如:
PID COMMAND %MEM %CPU
1 java 92.1 380
说明问题集中在 Java 进程。
如果是 Python:
python
gunicorn
uwsgi
也可以快速定位。
Linux 会使用空闲内存作为文件缓存。
查看:
cat /proc/meminfo
重点关注:
MemFree
Cached
Buffers
SReclaimable
如果:
Cached: 12GB
说明大量内存属于缓存,而不是应用真正占用。
进一步查看:
slabtop
确认是否为 Slab Cache 增长。
查看容器是否触发过 OOM:
docker inspect java-api | grep -i OOM
或者:
dmesg | grep -i "Killed process"
例如:
Out of memory:
Killed process 3567 (java)
说明内存已经耗尽,被内核强制终止。
Docker 使用 Cgroup 管理资源。
查看:
cat /sys/fs/cgroup/memory/docker/
Cgroup v2:
cat /sys/fs/cgroup/
查看限制:
cat /sys/fs/cgroup/
能够确认:
实际使用内存
限制内存
是否接近上限
如果是 Java:
jcmd
或者:
jmap -histo
查看对象数量:
byte[]
HashMap
String
如果对象持续增长,就需要进一步分析 Heap Dump。
Python 可使用:
python -m tracemalloc
Go 程序:
curl http://www.landui.com:6060/debug/pprof/heap
结合 pprof 分析内存分配。
很多生产环境没有限制容器内存。
例如:
docker run nginx
推荐:
docker run \\
--memory=2g \\
--memory-swap=2g \\
--cpus=2 \\
nginx
Docker Compose:
services:
api:
image: my-api
deploy:
resources:
limits:
memory: 2G
即使程序发生内存泄漏,也不会拖垮整台宿主机。
每分钟记录一次资源使用:
while true
do
docker stats --no-stream >> /var/log/docker_mem.log
sleep 60
done
统计增长最快的容器:
grep "java-api" /var/log/docker_mem.log
结合 Prometheus + cAdvisor + Grafana,可以长期监控:
Container Memory Usage
RSS
Cache
Working Set
OOM Count
比出现故障后再排查更有效。
某业务服务器部署了:
Docker
Nginx
Redis
Java API
凌晨开始内存持续上涨:
32GB
↓
31GB
↓
30GB
↓
OOM
最初怀疑是 Redis,但通过:
docker stats
发现:
Redis:600MB
Nginx:80MB
Java:14GB
进一步分析 Heap Dump,发现缓存对象未设置过期时间,大量 HashMap 长期驻留内存。
优化后:
· 增加缓存淘汰策略。
· 设置 JVM 最大堆大小。
· 为容器配置 --memory 限制。
· 接入 Prometheus 持续监控。
优化完成后:
容器内存稳定在 3.5GB~4GB
连续运行两个月无 OOM
宿主机内存使用率保持在 60% 以下
在 Docker 运维中,内存持续增长并不一定意味着宿主机故障,也可能是应用缓存、内存泄漏或资源限制配置不合理导致。通过 docker stats、Cgroup、应用内存分析工具以及持续监控相结合,才能快速定位问题根源,而不是依赖重启容器来暂时掩盖问题。
售前咨询
售后咨询
备案咨询
二维码

TOP