当我使用docker-compose和dockerfile创建javaproject时,我如何改变堆大小?



我想使用docker-compose缩放堆大小时,我需要,我失败了,我需要你的帮助,请!!

  • Dockerfile:
FROM openjdk:8-jdk
MAINTAINER whywhathow(whywhathow.fun@gmail.com)
ENV 
JVM_GC="UseParallelGC"
JVM_XMS="128m" 
JVM_XMX="256m"  
NACOS_ADDR="127.0.0.1:8848" 
JAVA_OPTS="-Xms${JVM_XMS} -Xmx${JVM_XMX}-XX:+${JVM_GC} -Djava.security.egd=file:/dev/./urandom"
PARAMS="--server.port=8080 --spring.profiles.active=prod --spring.cloud.nacos.server-addr=${NACOS_ADDR} --spring.cloud.nacos.config.namespace=prod --spring.cloud.nacos.config.file-extension=yml"
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
COPY ./*.jar /app.jar
#EXPOSE 8080
ENTRYPOINT ["/bin/sh","-c","java  ${JAVA_OPTS} -jar app.jar ${PARAMS}"]
  • docker-compose.yml
  • version: '3'
    services:
    ruoyi-gateway:
    build:
    context: ./service/gateway/
    container_name: ruoyi-gateway
    image: ruoyi-gateway
    ports:
    - "8080:8080"
    environment:
    JVM_XMS: 256m
    JVM_XMX: 256m
    JVM_GC: UseG1GC
    

    所以,我相信我的配置文件可以工作。我错了,我找到了问题,错误信息列表:

    "Mounts": [],
    "Config": {
    "Hostname": "7a5862c10b9b",
    "Domainname": "",
    "User": "",
    "AttachStdin": false,
    "AttachStdout": false,
    "AttachStderr": false,
    "ExposedPorts": {
    "8080/tcp": {}
    },
    "Tty": false,
    "OpenStdin": false,
    "StdinOnce": false,
    "Env": [
    "JVM_XMS=256m",
    "JVM_XMX=256m",
    "JVM_GC=UseG1GC",
    "PATH=/usr/local/openjdk-8/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
    "JAVA_HOME=/usr/local/openjdk-8",
    "LANG=C.UTF-8",
    "JAVA_VERSION=8u312",
    "NACOS_ADDR=121.41.120.209:8848",
    "JAVA_OPTS=-Xms -Xmx-XX:+ -Djava.security.egd=file:/dev/./urandomPARAMS=--server.port=8080 --spring.profiles.active=prod --spring.cloud.nacos.server-addr= --spring.cloud.nacos.config.namespace=prod --spring.cloud.nacos.config.file-extension=yml"
    ],
    "Cmd": null,
    "Image": "ruoyi-gateway",
    "Volumes": null,
    "WorkingDir": "",
    "Entrypoint": [
    "/bin/sh",
    "-c",
    "java  ${JAVA_OPTS} -jar app.jar ${PARAMS}"
    ],
    

    docker inspect information

    DockerfileENV指令只能引用已经定义的环境变量。如果没有shell hack,就无法定义依赖于其他变量最终具有的值的环境变量。

    对于JVM堆大小的特定情况,从Java 8 update 131开始,JVM知道如何查看Docker内存限制。从Java 8 update 190开始,默认的最大堆大小是可用内存的25%,但是您可以更改它,例如

    ENV JAVA_OPTS="-XX:MaxRAMPercentage=75 ..." # but no -Xmx
    

    并使用docker run -m选项设置容器内存限制。例如设置docker run -m 1g,则JVM堆大小为768 MiB。

    如果没有这个选项,我会通过在执行时设置JVM选项来解决这个问题。编写一个脚本设置$JAVA_OPTS,然后运行作为命令行参数传递给它的一些命令。

    #!/bin/sh
    # docker-entrypoint.sh
    # Set JVM memory options if set as environment variables.
    if [ -n "$JVM_XMS" ]; then
    JAVA_OPTS="$JAVA_OPTS -Xms$JVM_XMS"
    fi
    if [ -n "$JVM_XMX" ]; then
    JAVA_OPTS="$JAVA_OPTS -Xmx$JVM_XMX"
    fi
    # Then run the main container command.
    exec "$@"
    

    在Dockerfile中,您不需要在默认JVM选项中设置-Xmx,因为入口点脚本会为您添加它。您需要将此脚本命名为DockerENTRYPOINT

    ENV ... 
    JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom" 
    ...
    COPY docker-entrypoint.sh /
    ENTRYPOINT ["/docker-entrypoint.sh"]         # must be JSON array form
    CMD java ${JAVA_OPTS} -jar app.jar ${PARAMS} # Docker inserts `sh -c`
    

    对于各种Spring设置,我可能还会考虑使用环境变量而不是命令行参数。Spring都接受,但是增量地设置单独的环境变量比尝试重写$PARAMS列表要容易得多。

    ENV ... 
    SERVER_PORT=8080 
    SPRING_PROFILES_ACTIVE=prod 
    ...
    CMD java $JAVA_OPTS -jar app.jar # without $PARAMS
    

    作为最后一种变化,如果有一些东西需要常规地作为参数传递,那么可以将应用程序调用嵌入到入口点脚本中。这使得像获取调试shell (docker run --rm -it your-image bash)这样的事情变得更加困难,但更容易传递参数,而无需重复java命令(docker run -d your-image --option)。在此设置中,您将使用java命令结束入口点脚本,传递传递给脚本

    的任何参数。
    exec java $JAVA_OPTS -jar app.jar "$@"
    

    您不需要在Dockerfile中提到java命令,但是您需要在CMD中拼写出选项,必须是JSON-array形式(一个选项对应一个数组项)。在此设置中不能使用环境变量或其他shell替换。

    # if this runs `java -jar app.jar`
    ENTRYPOINT ["/docker-entrypoint.sh"]
    # then include additional options here -- MUST be a JSON array
    CMD ["--server.port=8080", "--spring.profiles.active=prod"]
    

    感谢David Maze的帮助。根据David Maze的回答,以下是我的答案。

    1. My flies structure:
    -docker
    |
    --services
    |
    ---demo
    |  |-docker-entrypoint.sh
    |  |-Dockerfile
    |
    -docker-compose.yml
    
    1. Dockerfile as list:
    FROM openjdk:8-jdk
    MAINTAINER whywhathow(whywhathow.fun@gmail.com)
    ENV 
    JVM_GC="+UseConcMarkSweepGC"
    JVM_XMS="128m" 
    JVM_XMX="256m"  
    SERVER_PORT="8080" 
    SPRING_PROFILES_ACTIVE="prod" 
    NACOS_ADDR="127.0.0.1" 
    JAVA_RANDOM="-Djava.security.egd=file:/dev/./urandom"
    RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
    COPY ./*.jar /app.jar
    #EXPOSE 8080
    #ENTRYPOINT ["/bin/sh","-c","java  ${JAVA_OPTS} -jar app.jar ${PARAMS}"]
    # test shell
    COPY ./docker-entrypoint.sh /docker-entrypoint.sh
    RUN chmod +x /docker-entrypoint.sh
    ENTRYPOINT ["/docker-entrypoint.sh"]
    
    1. docker-entrypoint.sh as list
    #!/bin/bash
    # docker-entrypoint.sh
    # link: https://stackoverflow.com/questions/69718900/how-can-i-change-heap-size-when-i-use-docker-compose-and-dockerfile-to-create-a
    # print debug information
    set -ex
    #########################################################
    # Set JVM memory options if set as environment variables.
    #########################################################
    if [ -n "${JVM_XMS}" ]; then
    JAVA_OPTS="$JAVA_OPTS -Xms$JVM_XMS "
    fi
    if [ -n "$JVM_XMX" ]; then
    JAVA_OPTS="$JAVA_OPTS -Xmx$JVM_XMX "
    fi
    # shellcheck disable=SC1072
    if [ -n "$JVM_GC" ]; then
    JAVA_OPTS="$JAVA_OPTS -XX:$JVM_GC"
    fi
    if [ -n "$JAVA_RANDOM" ]; then
    JAVA_OPTS="$JAVA_OPTS $JAVA_RANDOM"
    fi
    #########################################################
    # set params
    #########################################################
    # shellcheck disable=SC1073
    if [ -n  "$SERVER_PORT" ]; then
    PARAMS="$PARAMS --server.port=$SERVER_PORT "
    fi
    if [ -n  "$SPRING_PROFILES_ACTIVE" ]; then
    PARAMS="$PARAMS --spring.profiles.active=$SPRING_PROFILES_ACTIVE "
    fi
    if [ -n  "$NACOS_ADDR" ]; then
    PARAMS="$PARAMS --spring.cloud.nacos.server-addr=$NACOS_ADDR"
    fi
    if [ -n "$OTHER_PARAMS" ];  then
    PARAMS="$PARAMS $OTHER_PARAMS"
    fi
    # Then run the main container command.
    exec  java $JAVA_OPTS -jar  app.jar $PARAMS
    
    4
  • docker-compose。
  • 之后,您可以轻松地在docker- composer .yml中管理您的项目详细信息。

    提示:如果你是docker和shell脚本的新手,你应该看看这些东西。

    • Dockfile:
    • shell:确保你的shell没有错误(不要像我一样忽略编辑器错误信息,这太愚蠢了。)
      • if [-n "JVM_OPTIONS"];然后

    如果你像我一样在dockerfile和shell脚本中犯了错误,你应该在你的命令中注意。

    docker-compose up demo 
    

    找到你的问题并解决它。最后,感谢David Maze。

    相关内容

    • 没有找到相关文章

    最新更新