限制Docker容器中的JVM内存消耗

Xtr*_*ica 7 java docker spring-boot docker-compose

我有一个Spring Boot应用程序实现了一个我想在Docker容器中运行的服务.我遵循官方Spring文档的指导原则,建议创建类似于此的DockerFile:

FROM frolvlad/alpine-oraclejdk8:slim
VOLUME /tmp
ADD gs-spring-boot-docker-0.1.0.jar app.jar
RUN sh -c 'touch /app.jar'
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
Run Code Online (Sandbox Code Playgroud)

然后一旦图像被推送到Docker我使用Docker Compose以这种方式启动它:

  spring-boot-docker:
    ports:
    - "80:80"
    expose:
    - "80"
    image: my-repo/spring-boot-docker:0.1.0-SNAPSHOT
    container_name: spring-boot-docker
    environment:
      JAVA_OPTS: '-Xmx64m'
Run Code Online (Sandbox Code Playgroud)

这里我得到了JAVA_OPTS限制内存分配的变量,但是,当我执行时docker stats spring-boot-docker,容器占用的内存过多(我知道JVM占用的总内存可能远远超过64M,但在这种情况下完全是无边).

我也尝试过这个mem_limit参数,但这显然会减慢应用程序的速度.

Xtr*_*ica 7

经过一段时间的努力之后,似乎JAVA_OPTS变量可以在基于Tomcat映像的情况下传递给容器,但Spring Boot使用Java本身作为基本映像.

我发现本教程解决了我的问题,只是修改了DockerFile中启动进程的方式,并直接在ENTRYPOINT中添加了一个JAVA_OPTS变量:

ENTRYPOINT exec java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar
Run Code Online (Sandbox Code Playgroud)

这样,JVM将从命令本身中选择值.

  • 请注意,从"ENTRYPOINT"的_exec_切换到_shell_形式也会产生禁用{`CMD`,命令行参数}的副作用,因此运行容器就像`docker run <image> --spring.profiles.active = production`将忽略该配置文件. (3认同)