【问题标题】:Limit JVM memory consumption in a Docker container限制 Docker 容器中的 JVM 内存消耗
【发布时间】:2016-09-26 04:44:20
【问题描述】:

我有一个 Spring Boot 应用程序实现了我想在 Docker 容器中运行的服务。我遵循了官方Spring docs 的指导方针,它建议创建一个类似于这样的 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"]

然后,一旦图像被推送到 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'

这里我有一个限制内存分配的JAVA_OPTS 变量,但是,当我执行docker stats spring-boot-docker 时,容器占用的内存过多(我知道JVM 占用的总内存可能更多大于 64M,但在这种情况下完全是无限的)。

我也尝试过使用mem_limit param,但这会显着降低应用程序的速度。

【问题讨论】:

    标签: java docker spring-boot docker-compose


    【解决方案1】:

    苦苦挣扎了一会儿,貌似JAVA_OPTS变量可以传递给容器when it's based in a Tomcat image,但是Spring Boot使用Java本身作为基础镜像。

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

    ENTRYPOINT exec java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar
    

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

    【讨论】:

    • 请注意,从ENTRYPOINTexec 形式切换到shell 形式还有禁用{CMD, 命令的副作用line arguments} 所以像docker run <image> --spring.profiles.active=production 这样运行你的容器只会忽略配置文件。
    猜你喜欢
    • 2014-09-02
    • 2021-03-29
    • 2016-05-24
    • 1970-01-01
    • 2017-09-13
    • 2015-11-30
    • 1970-01-01
    • 2012-08-04
    • 1970-01-01
    相关资源
    最近更新 更多