需求描述:
在编写Dockerfile的java启动脚本的时候, 需要在oom的时dump快照, 这个时候的dump文件需要指定目录, 由于是微服务, 这个目录不能写死, 需要通过外层传参进来, 最终的文件如下:
FROM ubuntu:20.04
# 安装必要的软件包
RUN apt-get update && \
apt-get install -y --no-install-recommends \
ca-certificates \
curl \
&& rm -rf /var/lib/apt/lists/*
# 下载并安装Java 17
RUN curl -sL https://download.java.net/java/GA/jdk17/0d483333a00540d886896bac774ff48b/35/GPL/openjdk-17_linux-x64_bin.tar.gz | tar xz -C /usr/local
ENV JAVA_HOME=/usr/local/jdk-17
ENV PATH=$PATH:$JAVA_HOME/bin
# 验证Java
RUN java -version
ARG JAR_PATH
COPY ${JAR_PATH} app.jar
ENV TZ=Etc/UTC
ENV LANG C.UTF-8
RUN echo "${TZ}" > /etc/timezone \
&& ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime
#================设置环境变量,并且赋值================
ENV MODULE_PATH=$MODULE
RUN echo "===MODULE:$MODULE_PATH==="
#================使用sh的方式执行命令================
# 这里的启动参数需根据的实际情况来修改
CMD ["sh", "-c", "java \
-XX:+UseZGC \
-Xms1228m \
-Xmx1228m \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/var/log/$MODULE_PATH/ \
--add-opens java.base/java.math=ALL-UNNAMED \
--add-opens java.base/java.lang=ALL-UNNAMED \
--add-opens java.base/java.util=ALL-UNNAMED \
--add-opens java.base/java.net=ALL-UNNAMED \
--add-opens java.base/java.time=ALL-UNNAMED \
--add-opens java.base/sun.net.www.protocol.https=ALL-UNNAMED \
--add-opens java.base/java.lang.invoke=ALL-UNNAMED \
--add-opens java.base/java.lang.reflect=ALL-UNNAMED \
-jar app.jar"]
HeapDumpPath
文件最好不能指定文件名, /var/log/heapdump.hprof, 这样会导致第二次生成dump文件报错. 写路径也有弊端, 会生成多个文件,最好写脚本控制1个dump文件
外层的ci脚本传参如下方式
docker build --build-arg JAR_PATH=${JAR_PATH} --build-arg MODULE=${MODULE} -f ${DOCKER_FILE} -t ${docker_name} .