在 Spring Boot 2.3.0 中运行 mvn spring-boot:build-image 命令以生成 docker 镜像时如何设置 JVM 参数?

Vij*_*SRJ 6 spring jvm docker spring-boot

我正在尝试使用最新版本的 Spring Boot (2.3.0) 构建一个 docker 镜像。我现在需要创建一个映像,只需运行命令 mvn:spring-boot:build-image 。这将为我创建一个 docker 镜像。在这种情况下,如何设置 JVM 参数(最大、最小堆大小)?

小智 14

重建环境变量

当我在 2020 年 11 月开始使用 Spring Boot 2.3 和 BuildPacks 时,我尝试设置 JVM 参数,但无济于事并放弃/把它放在一边。

两周前,我再次拿起它,纯粹是偶然发现了这个: https: //github.com/paketo-buildpacks/environment-variables

基本上,您为环境变量添加前缀BPE_APPEND_,这会触发环境变量构建包将您的值附加到环境变量中。

注意:JAVA_TOOL_OPTIONS是你想要的,而不是JAVA_OPTS.

我需要附加一个 Java 代理来监控我们的微服务,像这样的build.gradle代码片段是有效的:

bootBuildImage {
  environment = [
    'BPE_DELIM_JAVA_TOOL_OPTIONS' : ' ',
    'BPE_APPEND_JAVA_TOOL_OPTIONS' : '-javaagent:my-java-agent.jar'
    ]
}
Run Code Online (Sandbox Code Playgroud)

我使用 BPE_DELIM_JAVA_TOOL_OPTIONS 来确保在附加我的值之前将空格添加到 JAVA_TOOL_OPTIONS 的现有值中构建包还允许您覆盖或添加到现有值 - 请参阅其自述文件)。

PS:我的值更像是'-javaagent:my-java-agent-${some-dynamic-version}.jar',所以我需要双引号,但这使它成为一个不起作用的 Gradle 字符串,所以我不得不写这个"-javaagent:my-java-agent-${some-dynamic-version}.jar".toString()


小智 5

截至今天,您无法在 spring-boot:build-image 中设置 JVM 参数。

Spring Boot 构建映像在内部使用 Packeto,它接受bellsoft-liberica GitHub 中提到的以下 4 个环境变量。

"BP_JVM_VERSION" : "13.0.1",  
"BPL_JVM_HEAD_ROOM" : "10",
"BPL_JVM_LOADED_CLASS_COUNT" : "35", 
"BPL_JVM_THREAD_COUNT" : "10"
Run Code Online (Sandbox Code Playgroud)

作为替代选项,您可以在运行映像时传递 JVM 参数。

docker run -p 8080:8080 --env JAVA_OPTS="-Xmx300m -Xms200m" -t youImageName

如果使用 Kubernetes,您可以在部署级别配置 JVM 选项。

    spec:
      containers:
      - name: yourapp
        image: image path
        ports:
        - containerPort: 8080
        env:
        - name: SPRING_PROFILES_ACTIVE
          value: "prod"    
        - name: BPL_JVM_HEAD_ROOM
          value: "2"  
        - name: BPL_JVM_LOADED_CLASS_COUNT
          value: "35"  
        - name: BPL_JVM_THREAD_COUNT
          value: "10"  
        - name: JAVA_OPTS
          value: >-
                -XX:ReservedCodeCacheSize=40M
                -XX:MaxMetaspaceSize=60M
                -Xlog:gc
                -Xms34m
                -Xmx40m
                -Xss256k
                -XX:MaxRAM=150M

Run Code Online (Sandbox Code Playgroud)

Spring boot 存储库中打开了一个 GitHub 问题,讨论了这个Failed to change JVM arguments for buildpacked image


Dan*_*usa 5

这些答案都没有完全正确。这是撰写本文时的完整情况。

重要的是要理解代码运行有两个不同的时间:构建时和运行时。

  1. 您可以在构建时使用 Maven 或 Gradle 配置中的 Spring Boot 设置环境变量。您只需给它一个要设置的环境变量列表即可。请参阅此处https://docs.spring.io/spring-boot/docs/2.3.x/maven-plugin/reference/html/#build-image-customization不过,这些只会在构建时设置。不是你想要设置的东西之类的-Xmx

  2. 如果您希望在运行时设置环境变量,那么这不是 Spring Boot 或 buildpack 可以控制的。这不是两者的失败,只是两者都没有参与实际运行您的应用程序映像/容器。

    要在运行时将环境变量传递到应用程序映像/容器,您需要使用运行应用程序映像的任何工具,例如 Docker 或 Kubernetes。对于 Docker 来说,这只是docker run -e foo=bar .... 对于 Kubernetes,它位于pod 规范中。

    供参考。任何以 为前缀的 env 变量都BPL_意味着它在运行时应用(L用于启动,这就是 buildpack 术语中的运行时环境)。因此,只有在应用程序运行时设置这些才有意义。

  3. 其他答案中提到的环境变量 buildpack是两者的混合。如果您使用上面的选项 #1 设置环境变量,但以某种方式添加前缀,则此 buildpack 将看到它们并将它们转换为嵌入到图像中的环境变量。这将产生在运行时设置它们的效果。

    如果您想在图像上设置默认值,这很有效。然后,图像的用户将不需要设置它们,除非他们需要偏离图像作者设置的默认值。话虽如此,您永远不会想将其用于任何敏感或秘密的事情。这是因为环境变量和值最终出现在图像中,因此任何有权访问该图像的人都可以看到该值。

回答这个问题:

在这种情况下,如何设置 JVM 参数(最大、最小堆大小)?

  1. 如果您想设置图像用户可以覆盖的默认值(如果需要),那么您需要环境变量 buildpack

    前任:

            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <image>
                        <env>
                            <BPE_APPEND_JAVA_TOOL_OPTIONS>-Xss256k</BPE_APPEND_JAVA_TOOL_OPTIONS>
                            <BPE_DELIM_JAVA_TOOL_OPTIONS> </BPE_DELIM_JAVA_TOOL_OPTIONS>
                        </env>
                    </image>
                    <layers>
                        <enabled>true</enabled>
                    </layers>
                </configuration>
            </plugin>
    
    Run Code Online (Sandbox Code Playgroud)

    您将看到如下输出:

    [INFO]     [creator]     Paketo Environment Variables Buildpack 3.1.1
    [INFO]     [creator]       https://github.com/paketo-buildpacks/environment-variables
    [INFO]     [creator]       Launch Configuration:
    [INFO]     [creator]         $BPE_<NAME>             prepend value to $NAME, delimiting with OS path list separator
    [INFO]     [creator]         $BPE_APPEND_<NAME>      append value to $NAME
    [INFO]     [creator]         $BPE_DEFAULT_<NAME>     set default value for $NAME
    [INFO]     [creator]         $BPE_DELIM_<NAME>       set delimeter to use when appending or prepending to $NAME
    [INFO]     [creator]         $BPE_OVERRIDE_<NAME>    set $NAME to value
    [INFO]     [creator]         $BPE_PREPEND_<NAME>     prepend value to $NAME
    [INFO]     [creator]       Environment Variables: Contributing to layer
    [INFO]     [creator]         Writing env.launch/JAVA_TOOL_OPTIONS.append
    
    Run Code Online (Sandbox Code Playgroud)

    当您运行图像的实例时,您设置的值应该传递到容器,除非用户覆盖它们。

    > docker run -it apps/maven
    Setting Active Processor Count to 6
    Calculating JVM memory based on 9057276K available memory
    Calculated JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -Xmx8699636K -XX:MaxMetaspaceSize=88839K -XX:ReservedCodeCacheSize=240M (Total Memory: 9057276K, Thread Count: 50, Loaded Class Count: 13271, Headroom: 0%)
    Adding 129 container CA certificates to JVM truststore
    Spring Cloud Bindings Enabled
    Picked up JAVA_TOOL_OPTIONS: -Djava.security.properties=/layers/paketo-buildpacks_bellsoft-liberica/java-security-properties/java-security.properties -agentpath:/layers/paketo-buildpacks_bellsoft-liberica/jvmkill/jvmkill-1.16.0-RELEASE.so=printHeapHistogram=1 -Xss256k -XX:ActiveProcessorCount=6 -XX:MaxDirectMemorySize=10M -Xmx8699636K -XX:MaxMetaspaceSize=88839K -XX:ReservedCodeCacheSize=240M -Dorg.springframework.cloud.bindings.boot.enable=true
    
    Run Code Online (Sandbox Code Playgroud)
  2. 如果您想设置这些值,只需在运行时设置它们即可。例如:docker run -e JAVA_TOOL_OPTIONS '-Xss256k' ...或者在您的 Kubernetes pod 规范中,如下所示。

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-cool-app
      labels:
        purpose: my-cool-app-label
    spec:
      containers:
      - name: my-cool-app
        image: my-cool-image
        env:
        - name: JAVA_TOOL_OPTIONS
          value: "-Xss256k"
    
    Run Code Online (Sandbox Code Playgroud)

    当容器运行时,您将看到类似的输出,并将显示您在本示例中Picked up JAVA_TOOL_OPTIONS:设置的值。-Xss256k

  • 一个提示 - 将 ` xml:space="preserve"` 添加到 BPE_DELIM_JAVA_TOOL_OPTIONS,因此它是 `&lt;BPE_DELIM_JAVA_TOOL_OPTIONS xml:space="preserve"&gt; &lt;/BPE_DELIM_JAVA_TOOL_OPTIONS&gt;` 如果没有它,空格作为分隔符将被忽略 (3认同)