本文主要针对docker来部署java程序的时候,常常会出现内存占有很大的问题,通过调整docker的配置来限制内存占用
本文目录
- 问题复现
- 调整配置
1.问题复现
测试环境下服务器的配置为24核64G内存,启动微服务,在没有进行内存限制的时候,我们通过docker stats
命令查看一下微服务的内存占用,如下图
我们发现8个微服务占用了将近24G的内存,最大的一个服务占用了将近8个G的内存,这显然是不合理的
我们看一下Dockerfile文件的配置
FROM registry.cn-beijing.aliyuncs.com/sxd/ubuntu-java8:1.0
MAINTAINER helloworld
ADD bin/start.sh /root/
RUN chmod u+x /root/start.sh
CMD ["/root/start.sh","dev -Dcache"]
对应的启动脚本start.sh
的配置如下:
#!/bin/bash
#### normal dev model
#nohup java -jar -Dspring.profiles.active=dev $1 target/myservice.jar > out.log $1 2>&1 &
nohup java -jar target/myService.jar -Dspring.profiles.active=$1 $2 > out.log 2>&1 &
tail -100f order.log
我们再看一下docker-compose的配置
version: '2'
services:
centerservice:
container_name: myservice-1
build:
context: .
dockerfile: Dockerfile
restart: always
ports:
- "8001:8001"
volumes:
- ../target/myservice.jar:/root/target/myservice.jar
配置中都没有对docker内存以及jvm内存做任何限制,导致了我们docker容器启动,占用内存过大的问题
2.调整配置
2.1 调整jvm启动参数配置
首先我们对java启动时jvm内存大小做个调整,增加jvm启动参数-Xms1024M -Xmx1024M -Xmn256M -Xss256K
调整后的启动脚本start.sh
如下:
#!/bin/bash
#### normal dev model
#nohup java -jar -Dspring.profiles.active=dev $1 target/myservice.jar > out.log $1 2>&1 &
nohup java -jar -Xms1024M -Xmx1024M -Xmn256M -Xss256K target/myService.jar -Dspring.profiles.active=$1 $2 > out.log 2>&1 &
tail -100f order.log
调整完jvm启动参数之后,重新启动容器,结果如下:
发现内存使用上已经根据我们调整的大小降了下来
2.2 调整容器启动内存限制
到这里,问题基本解决,不过看到容器的内存限制还是62G,这样显然还是不合理的,我们也要对容器进行调整,调整方式有两种
- 方式一:在启动镜像的时候,指定容器内存大小:
docker run -it -m 200M 镜像名
直接指定容器最多使用 200M 物理内存和 200M swap。
- 方式二:使用docker-compose 配置文件来配置容器内存大小的限制
v2版本中,直接加入mem_limit: 1024m #最大内存使用不超过1024m
其中mem_limit用于控制容器默认启动时会使用 1/16*物理内存的现象,导致几个服就占满了全部内存。
v3版本中,配置如下:
deploy:
resources:
limits:
memory: 200M
#cpus: '0.50' 加入cpu限制
reservations:
memory: 100M
注意 deploy 仅 docker deploy stack 生效
或使用 docker-compose --compatibility up 生效
配置完成之后,重启docker服务,如下图:
容器内存限制发生了变化,达到了我们的预期效果
参考:
1.JVM常用启动参数
2.如何限制docker容器的内存大小
3.在Docker Compose file 3下限制CPU与内存