一、概述
基于Java语言的应用,需要通过环境变量 $JAVA_OPTS
来指定JVM虚拟机使用的内存大小。如果不加以指定直接运行,将会出现内存泄漏的现象。
Rainbond 在设计之初已经想到了这一点,并对由 Java源码创建的应用,基于伸缩选项中分配的内存大小,动态的设置了 $JAVA_OPTS。在定义应用的启动方式时,可以直接调用。比如按如下方式定义 Procfile:
web: java -jar $JAVA_OPTS demo.jar
而对于用户自定义的镜像部署的Java语言应用,则应该由人工的方式,动态指定这个变量,再按照用户定义的方式启动应用。
二、 动态识别内存脚本
首先,应在项目 Dockerfile
同级目录下添加 setmem.sh
,用来动态获取 Rainbond 伸缩选项中定义的内存大小,并据此生成 $JAVA_OPTS
变量。该脚本内容如下:
# set JAVA_OPTS env
case $MEMORY_SIZE in
"micro")
export JAVA_OPTS="-Xms90m -Xmx90m -Xss512k -XX:MaxDirectMemorySize=12M"
echo "Optimizing java process for 128M Memory...." >&2
;;
"small")
export JAVA_OPTS="-Xms180m -Xmx180m -Xss512k -XX:MaxDirectMemorySize=24M "
echo "Optimizing java process for 256M Memory...." >&2
;;
"medium")
export JAVA_OPTS="-Xms360m -Xmx360m -Xss512k -XX:MaxDirectMemorySize=48M"
echo "Optimizing java process for 512M Memory...." >&2
;;
"large")
export JAVA_OPTS="-Xms720m -Xmx720m -Xss512k -XX:MaxDirectMemorySize=96M "
echo "Optimizing java process for 1G Memory...." >&2
;;
"2xlarge")
export JAVA_OPTS="-Xms1420m -Xmx1420m -Xss512k -XX:MaxDirectMemorySize=192M"
echo "Optimizing java process for 2G Memory...." >&2
;;
"4xlarge")
export JAVA_OPTS="-Xms2840m -Xmx2840m -Xss512k -XX:MaxDirectMemorySize=384M "
echo "Optimizing java process for 4G Memory...." >&2
;;
"8xlarge")
export JAVA_OPTS="-Xms5680m -Xmx5680m -Xss512k -XX:MaxDirectMemorySize=768M"
echo "Optimizing java process for 8G Memory...." >&2
;;
16xlarge|32xlarge|64xlarge)
export JAVA_OPTS="-Xms8G -Xmx8G -Xss512k -XX:MaxDirectMemorySize=1536M"
echo "Optimizing java process for biger Memory...." >&2
;;
*)
export JAVA_OPTS="-Xms512m -Xmx512m -Xss512k -XX:MaxDirectMemorySize=24M"
echo "MEMORY_SIZE environment variable is not set, use the default memory settings" >&2
;;
esac
定义完该脚本后,定义 Dockerfile ,将该脚本添加到镜像构建流程中:
FROM openjdk:1.8
···
COPY setmem.sh /setmem.sh
···
#启动命令为启动脚本
ENTRYPOINT ["/docker-entrypoint.sh"]
最后,在启动脚本 docker-entrypoint.sh 中,加载 setmem.sh ,并在运行的时候指定 $JAVA_OPTS即可。示例启动脚本如下:
#!/bin/bash
#加载动态识别内存脚本
source /setmem.sh
#规定其他操作
do something
#最终启动命令
java -jar $JAVA_OPTS demo.jar
通过上述方式构建的镜像,在部署到Rainbond后,就可以根据伸缩中设置的内存大小,动态指定 JVM 内存,从而防止内存泄漏。