kubernetes 动态限制tomcat 内存
1 通过 修改catalina.sh中的配置内存的形式限制tomcat 内存
JAVA_OPTS="-server -Xms1024m -Xmx2048m -XX:MaxNewSize=256m -XX:PermSize=128m -XX:MaxPermSize=256m"
2 通过docker run 的时候指定参数
docker run --rm -e JAVA_OPTS='-Xmx512m' tomcat:8
3 通过指定一个参数 留出固定的内存
自从1.7版本之后,Docker把容器的local cgroups以只读方式挂载到容器内部的文件系统上,这样我们就可以在容器内部,通过cgroups信息来获取系统对当前容器的资源限制了。
启动脚本会检查CGroup中内存限置,并计算JVM最大Heap size来传递给Tomcat。其代码如下:
https://github.com/denverdino/docker-tomcat-autoheap?spm=a2c6h.12873639.0.0.135f63bfL9tf2c
#!/bin/bash
limit_in_bytes=$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes)
# If not default limit_in_bytes in cgroup
if [ "$limit_in_bytes" -ne "9223372036854771712" ]
then
limit_in_megabytes=$(expr $limit_in_bytes \/ 1048576)
heap_size=$(expr $limit_in_megabytes - $RESERVED_MEGABYTES)
export JAVA_OPTS="-Xmx${heap_size}m $JAVA_OPTS"
echo JAVA_OPTS=$JAVA_OPTS
fi
exec catalina.sh run
说明:这个我并未做测试
- 为了JVM自身的Non-Heap内存,以及监控,故障排查等场景,预留了部分内存(缺省256M),其余容器内存都分配给JVM的堆。
- 这里没有对边界情况做进一步处理。在生产系统中需要根据情况做相应的设定,比如最大的堆大小等等。
4 分配容器80%的内存给tomcat
修改tomcat的catalila.sh 添加如下
if [[ "$JAVA_OPTS" != *-Djava.security.egd=* ]]; then
JAVA_OPTS="$JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -XX:-OmitStackTraceInFastThrow -javaagent:/srv/jacoco/jacocoagent.jar=includes=*,output=tcpserver,append=true,destfile=/srv/tomcat/tomcat-haozhuo-ec/jacoco.exec,port=6309,address=0.0.0.0"
fi
limit_in_bytes=$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes)
if [ "$limit_in_bytes" -ne "9223372036854771712" ]
then
limit_in_megabytes=$(expr $limit_in_bytes / 1048576)
heap_size=$(expr $limit_in_megabytes / 5 \* 4)
export JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -XX:+DisableExplicitGC -XX:-OmitStackTraceInFastThrow -server -Xms${heap_size}m -Xmx${heap_size}m $JAVA_OPTS"
echo JAVA_OPTS=$JAVA_OPTS
fi
这里80% 采用了除5乘4的办法 注意乘 需要转义,如果用小数点,会导致参数heap_size 为空
效果
# 在master上获取yaml文件
kubectl get pod haozhuo-ec-dp-0 -n test -o yaml
# 进入容器执行
kubectl exec -it haozhuo-ec-dp-0 -c haozhuo-ec /bin/bash -n test
ps -ef |grep java
然后将tomcat 打成镜像即可