背景
截止至今,jdk稳定版本已经发展到了25,比起11/17/21等做了较大的性能提升,因此想做一个通用的镜像,以供线上使用,同时能减少内存的消耗
Dockerfile找准基准镜像
Haskell
# JRE 25,基于 Ubuntu 24.04 LTS
FROM eclipse-temurin:25-jre-noble
# 时区
ENV TZ="Asia/Shanghai"
# 创建用户及应用目录
RUN ln -snf "/usr/share/zoneinfo/${TZ}" /etc/localtime \
&& echo "${TZ}" > /etc/timezone \
&& groupadd --gid 10001 arvin \
&& useradd --uid 10001 \
--gid arvin \
--home-dir /apps \
--no-create-home \
--shell /usr/sbin/nologin \
arvin \
&& mkdir -p /apps/logs /apps/data /apps/tmp \
&& chown -R arvin:arvin /apps
# JVM 参数与 JAR 名称
ENV JAVA_OPTS=""
ENV JAR_NAME="app.jar"
WORKDIR /apps
# 业务镜像中按需启用
# COPY --chown=arvin:arvin *.jar /apps/app.jar
EXPOSE 8080
# 非 root 用户运行
USER arvin:arvin
# 支持 JVM 参数及 --是为了增加Spring Boot 启动参数(如果没有添加默认就是无参数启动)
ENTRYPOINT ["sh", "-c", "exec java $JAVA_OPTS -jar \"$JAR_NAME\" \"$@\"", "--"]
执行构建
docker build -t eclipse-temurin-jre25:noble .

生成的镜像

通用的单体启动脚本
Haskell
#!/bin/bash
# 查询当前路径下 用jar结尾的文件并根据最后修改时间排序,获取文件名
readonly c_name=haha
#$(ls *.jar -lt |head -n 1 | awk '{print substr($9,1,length($9)-4)}')
readonly user=0:0
readonly port=8880
readonly profiles_active=dev
readonly image_name=eclipse-temurin-jre25:noble
docker_run(){
echo "尝试删除容器-->"${c_name}
docker rm -f ${c_name} ;
echo "重新运行容器-->"${c_name}
docker run -d --network=host --security-opt seccomp=unconfined --name ${c_name} --user ${user} \
-e JAVA_OPTS="-Xms512m -Xmx512m -Dspring.profiles.active=${profiles_active} -Dserver.port=${port} -Duser.timezone=GMT+8" \
-e JAR_NAME=/apps/$1 \
-v /etc/hosts:/etc/hosts -v `pwd`:/apps/ \
-v /etc/localtime:/etc/localtime \
--restart=unless-stopped ${image_name}
}
if [ -n "$1" ]; then
docker_run $1
else
echo "没有指定默认的启动jar包-执行按照最后修改时间的最后一个jar文件-->"$(ls *.jar -lt |head -n 1| awk '{print $9}')
docker_run $(ls *.jar -lt |head -n 1| awk '{print $9}')
fi
可直接执行
通用的多服务配置新建docker-compose.yml
Haskell
services:
gateway-api:
image: eclipse-temurin-jre25:noble
# jre17-20240625:latest
container_name: gateway-api
# 因为有权限问题,先用root用户启动 0:0代表root用户
user: "0:0"
network_mode: host
security_opt:
- seccomp=unconfined
environment:
- JAVA_OPTS=-Xms${GATEWAY_MEMORY:-512m} -Xmx${GATEWAY_MEMORY:-512m} -Dspring.profiles.active=${PROFILES_ACTIVE:-dev} -Dserver.port=${GATEWAY_PORT:-8880} -Duser.timezone=GMT+8
- JAR_NAME=/apps/gateway-api.jar
volumes:
- ./gateway-api/:/apps/
- /etc/hosts:/etc/hosts
- /etc/localtime:/etc/localtime
restart: unless-stopped
# 【关键】不要写 entrypoint 和 command,让镜像自己决定
service-api:
image: eclipse-temurin-jre25:noble
container_name: service-api
user: "0:0"
network_mode: host
security_opt:
- seccomp=unconfined
environment:
- JAVA_OPTS=-Xms${SERVICE_MEMORY:-1024m} -Xmx${SERVICE_MEMORY:-1024m} -Dspring.profiles.active=${PROFILES_ACTIVE:-dev} -Dserver.port=${SERVICE_PORT:-8881} -Duser.timezone=GMT+8
- JAR_NAME=/apps/service-api.jar
volumes:
- ./service-api/:/apps/
- /etc/hosts:/etc/hosts
- /etc/localtime:/etc/localtime
restart: unless-stopped
auth-api:
image: eclipse-temurin-jre25:noble
container_name: auth-api
user: "0:0"
network_mode: host
security_opt:
- seccomp=unconfined
environment:
- JAVA_OPTS=-Xms${AUTH_MEMORY:-512m} -Xmx${AUTH_MEMORY:-512m} -Dspring.profiles.active=${PROFILES_ACTIVE:-dev} -Dserver.port=${AUTH_PORT:-8882} -Duser.timezone=GMT+8
- JAR_NAME=/apps/auth-api.jar
volumes:
- ./auth-api/:/apps/
- /etc/hosts:/etc/hosts
- /etc/localtime:/etc/localtime
restart: unless-stopped
agent-api:
image: eclipse-temurin-jre25:noble
container_name: agent-api
user: "0:0"
network_mode: host
security_opt:
- seccomp=unconfined
environment:
- JAVA_OPTS=-Xms${AGENT_MEMORY:-512m} -Xmx${AGENT_MEMORY:-512m} -Dspring.profiles.active=${PROFILES_ACTIVE:-dev} -Dserver.port=${AGENT_PORT:-8883} -Duser.timezone=GMT+8
- JAR_NAME=/apps/agent-api.jar
volumes:
- ./agent-api/:/apps/
- /etc/hosts:/etc/hosts
- /etc/localtime:/etc/localtime
restart: unless-stopped
启动效果

性能对比
JDK17的内存使用情况

JDK25的内存使用情况

内存使用上确实有明显的提升