亚洲国产日韩人妖另类,久久只有这里有精品热久久,依依成人精品视频在线观看,免费国产午夜视频在线

      
      

        Java 服務(wù) Docker 容器化最佳實(shí)踐

        一、概述

        當(dāng)我們在容器中運(yùn)行 Java 應(yīng)用程序時(shí),可能希望對其進(jìn)行調(diào)整參數(shù)以充分利用資源。

        在本教程中,我們將了解如何在運(yùn)行 Java 進(jìn)程的容器中設(shè)置 JVM 參數(shù)。本文將重點(diǎn)關(guān)注常見的 -Xmx 和-Xms 標(biāo)志。

        另外,我們還將研究使用某些 Java 版本運(yùn)行的程序容器化的常見問題,以及如何在常見的容器化 Java 應(yīng)用程序時(shí)設(shè)置自定義標(biāo)志。

        二、Java 容器中的默認(rèn)堆設(shè)置

        過去,JVM 不知道分配給容器的內(nèi)存和 CPU。

        Java 10 引入了一個新設(shè)置:+UseContainerSupport(默認(rèn)啟用)來修復(fù) 這個問題[3],并在 8u191[4] 中將修復(fù)反向移植到 Java 8 。

        現(xiàn)在 JVM 可以根據(jù)分配給容器的內(nèi)存計(jì)算其內(nèi)存。

        1. 自動內(nèi)存計(jì)算

        當(dāng)不設(shè)置-Xmx和-Xmx參數(shù)時(shí),JVM 會根據(jù)系統(tǒng)規(guī)格來調(diào)整堆大小。

        看看堆大?。?/p>

        $ java -XX:+PrintFlagsFinal -version | grep -Ei “maxheapsize|maxram”

        輸出結(jié)果如下:

        openjdk version “15” 2020-09-15OpenJDK Runtime Environment AdoptOpenJDK (build 15+36)OpenJDK 64-Bit Server VM AdoptOpenJDK (build 15+36, mixed mode, sharing) size_t MaxHeapSize = 4253024256 {product} {ergonomic} uint64_t MaxRAM = 137438953472 {pd product} {default} uintx MaxRAMFraction = 4 {product} {default} double MaxRAMPercentage = 25.000000 {product} {default} size_t SoftMaxHeapSize = 4253024256 {manageable} {ergonomic}

        我們看到 JVM 將其堆大小設(shè)置為可用 RAM 的大約 25%。在這個例子中,在一個 16GB 的系統(tǒng)上分配了 4GB。

        出于測試目的,創(chuàng)建一個文件,名為PrintXmxXms.java,內(nèi)容是以 MB 為單位打印堆大小,代碼內(nèi)容如下:

        import java.lang.management.ManagementFactory;import java.lang.management.MemoryMXBean;public class PrintXmxXms { public static void main(String[] args) { int mb = 1024 * 1024; MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean(); long xmx = memoryBean.getHeapMemoryUsage().getMax() / mb; long xms = memoryBean.getHeapMemoryUsage().getInit() / mb; System.out.println(“Initial Memory (xms) : ” + xms + “mb”); System.out.println(“Max Memory (xmx) : ” + xmx + “mb”); }}

        假設(shè)已經(jīng)安裝了 JDK,可以編譯程序并運(yùn)行:

        $ javac ./PrintXmxXms.java$ java -cp . PrintXmxXms

        在 16Gb RAM 的主機(jī)上,輸出結(jié)果為:

        INFO: Initial Memory (xms) : 254mbINFO: Max Memory (xmx) : 4056mb

        下面,在容器中嘗試一下。

      1. JDK 8u191 之前的版本在包含 PrintXmxXms.java 文件的文件夾中添加以下 Dockerfile:
      2. FROM openjdk:8u92-jdk-alpineCOPY *.java /src/RUN mkdir /app && ls /src && javac /src/PrintXmxXms.java -d /appCMD [“sh”, “-c”, “java -version && java -cp /app PrintXmxXms”]

        這里使用的容器使用舊版本的 Java 8,它早于更新版本中可用的容器支持。構(gòu)建鏡像:

        $ sudo docker build -t oldjava .

        Dockerfile 中的 CMD 行是運(yùn)行容器時(shí)默認(rèn)執(zhí)行的進(jìn)程。由于沒有提供-Xmx或-XmsJVM 標(biāo)志,內(nèi)存設(shè)置將是默認(rèn)設(shè)置。

        運(yùn)行容器:

        $ sudo docker run –rm -ti oldjavaopenjdk version “1.8.0_92-internal”OpenJDK Runtime Environment (build 1.8.0_92-…)OpenJDK 64-Bit Server VM (build 25.92-b14, mixed mode)Initial Memory (xms) : 198mbMax Memory (xmx) : 2814mb

        現(xiàn)在使用–memory=1g命令行標(biāo)志將容器內(nèi)存限制為 1GB:

        $ sudo docker run –rm -ti –memory=1g oldjavaopenjdk version “1.8.0_92-internal”OpenJDK Runtime Environment (build 1.8.0_92-…)OpenJDK 64-Bit Server VM (build 25.92-b14, mixed mode)Initial Memory (xms) : 198mbMax Memory (xmx) : 2814mb

        輸出完全相同。這證明舊的 JVM 沒有遵守容器內(nèi)存限制。

      3. JDK 8u130 之后的版本使用相同的測試程序,更改 Dockerfile 的第一行來使用 JVM 8 的新版本:
      4. FROM openjdk:8-jdk-alpine

        然后再次做測試:

        $ sudo docker build -t newjava .$ sudo docker run –rm -ti newjavaopenjdk version “1.8.0_212″OpenJDK Runtime Environment (IcedTea 3.12.0) (Alpine 8.212.04-r0)OpenJDK 64-Bit Server VM (build 25.212-b04, mixed mode)Initial Memory (xms) : 198mbMax Memory (xmx) : 2814mb

        如上輸出,使用整個 docker 主機(jī)內(nèi)存來計(jì)算 JVM 堆大小。但是,如果為容器分配 1GB 的 RAM:

        $ sudo docker run –rm -ti –memory=1g newjavaopenjdk version “1.8.0_212″OpenJDK Runtime Environment (IcedTea 3.12.0) (Alpine 8.212.04-r0)OpenJDK 64-Bit Server VM (build 25.212-b04, mixed mode)Initial Memory (xms) : 16mbMax Memory (xmx) : 247mb

        這一次,JVM 根據(jù)容器可用的 1GB RAM 計(jì)算堆大小。

        現(xiàn)在我們了解了 JVM 如何計(jì)算其默認(rèn)值以及為什么需要一個最新的 JVM 來獲得正確的默認(rèn)值。

        三、常用的基礎(chǔ)鏡像中內(nèi)存設(shè)置

      5. OpenJDK與其直接在容器命令上硬編碼 JVM 標(biāo)志,不如使用環(huán)境變量。例如在Dockerfile 中使用 JAVA_OPTS 變量,可以在啟動容器時(shí)對其進(jìn)行修改:
      6. FROM openjdk:8u92-jdk-alpineCOPY *.java /src/RUN mkdir /app && ls /src && javac /src/PrintXmxXms.java -d /appENV JAVA_OPTS=””CMD [“sh”, “-c”, “java -version && java $JAVA_OPTS -cp /app PrintXmxXms”]

        構(gòu)建鏡像:

        $ sudo docker build -t openjdk-java .

        通過指定JAVA_OPTS環(huán)境變量在運(yùn)行時(shí)選擇內(nèi)存設(shè)置:

        $ sudo docker run –rm -ti -e JAVA_OPTS=”-Xms50M -Xmx50M” openjdk-javaopenjdk version “1.8.0_92-internal”OpenJDK Runtime Environment (build 1.8.0_92-internal-alpine-r1-b14)OpenJDK 64-Bit Server VM (build 25.92-b14, mixed mode)Initial Memory (xms) : 50mbMax Memory (xmx) : 48mb

        注意:-Xmx 參數(shù)和 JVM 報(bào)告的 Max memory 之間存在細(xì)微差別。這是因?yàn)?Xmx 設(shè)置了內(nèi)存分配池的最大大小,其中包括堆、垃圾收集器的幸存者空間和其他池。

        2. Tomcat 9

        Tomcat 9 容器有自己的啟動腳本,因此要設(shè)置 JVM 參數(shù),需要使用這些腳本。

        bin/catalina.sh 腳本要求在環(huán)境變量 CATALINA_OPTS 中設(shè)置內(nèi)存參數(shù)。

        首先需要 創(chuàng)建一個 war 包 部署到 Tomcat。

        然后,我們使用下面的Dockerfile 對其進(jìn)行容器化,并在其中聲明CATALINA_OPTS環(huán)境變量:

        FROM tomcat:9.0COPY ./target/*.war /usr/local/tomcat/webapps/ROOT.warENV CATALINA_OPTS=”-Xms1G -Xmx1G”

        然后構(gòu)建容器鏡像并運(yùn)行它:

        $ sudo docker build -t tomcat .$ sudo docker run –name tomcat -d -p 8080:8080 -e CATALINA_OPTS=”-Xms512M -Xmx512M” tomcat

        注意:運(yùn)行時(shí),將新值傳遞給 CATALINA_OPTS 。如果不提供這個值,會使用 Dockerfile 的第 3 行給出的默認(rèn)值。

        可以檢查應(yīng)用的運(yùn)行時(shí)參數(shù)并驗(yàn)證選項(xiàng)-Xmx和-Xms是否存在:

        $ sudo docker exec -ti tomcat jps -lv1 org.apache.catalina.startup.Bootstrap -Xms512M -Xmx512M

        四、使用構(gòu)建插件

        Maven 和 Gradle 提供的插件允許我們在沒有Dockerfile的情況下創(chuàng)建容器鏡像。生成的鏡像通??梢栽谶\(yùn)行時(shí)通過環(huán)境變量進(jìn)行參數(shù)化。

        下面看幾個例子。

      7. 使用 Spring Boot從 Spring Boot 2.3 開始,Spring Boot Maven 和 Gradle 插件可以在沒有 Dockerfile 的情況下高效構(gòu)建容器。
      8. 使用 Maven 時(shí),將它們添加到 spring-boot-maven-plugin 中的 塊中:

        com.baeldung.docker heapsizing-demo 0.0.1-SNAPSHOT org.springframework.boot spring-boot-maven-plugin heapsizing-demo

        要構(gòu)建項(xiàng)目,運(yùn)行下面的命令:

        $ ./mvnw clean spring-boot:build-image

        這將產(chǎn)生一個名為 : 的鏡像。在這個例子中產(chǎn)生的鏡像名為:demo-app:0.0.1-SNAPSHOT。Spring Boot 底層使用 Cloud Native Buildpacks 作為容器化技術(shù)。

        該插件對 JVM 的內(nèi)存設(shè)置進(jìn)行硬編碼。但是,我們?nèi)匀豢梢酝ㄟ^設(shè)置環(huán)境變量JAVA_OPTS 或 JAVA_TOOL_OPTIONS 來覆蓋:

        $ sudo docker run –rm -ti -p 8080:8080 -e JAVA_TOOL_OPTIONS=”-Xms20M -Xmx20M” –memory=1024M heapsizing-demo:0.0.1-SNAPSHOT

        輸出將與此類似:

        Setting Active Processor Count to 8Calculated JVM Memory Configuration: […][…]Picked up JAVA_TOOL_OPTIONS: -Xms20M -Xmx20M[…]

      9. 使用谷歌 JIB就像 Spring Boot maven 插件一樣,Google JIB 無需 Dockerfile 即可高效創(chuàng)建 Docker 鏡像。Maven 和 Gradle 插件以類似的方式配置。Google JIB 還使用環(huán)境變量 JAVA_TOOL_OPTIONS 作為 JVM 參數(shù)的覆蓋機(jī)制。
      10. 我們可以在任何能夠生成可執(zhí)行 jar 文件的 Java 框架中使用 Google JIB Maven 插件。例如,可以在 Spring Boot 應(yīng)用程序中使用它來代替spring-boot-maven插件來生成容器鏡像:

        com.google.cloud.tools jib-maven-plugin 2.7.1 heapsizing-demo-jib

        鏡像是使用 mvn jib:dockerBuild 命令構(gòu)建的:

        $ mvn clean install && mvn jib:dockerBuild

        嘗試運(yùn)行:

        $ sudo docker run –rm -ti -p 8080:8080 -e JAVA_TOOL_OPTIONS=”-Xms50M -Xmx50M” heapsizing-demo-jibPicked up JAVA_TOOL_OPTIONS: -Xms50M -Xmx50M[…]2021-01-25 17:46:44.070 INFO 1 — [ main] c.baeldung.docker.XmxXmsDemoApplication : Started XmxXmsDemoApplication in 1.666 seconds (JVM running for 2.104)2021-01-25 17:46:44.075 INFO 1 — [ main] c.baeldung.docker.XmxXmsDemoApplication : Initial Memory (xms) : 50mb2021-01-25 17:46:44.075 INFO 1 — [ main] c.baeldung.docker.XmxXmsDemoApplication : Max Memory (xmx) : 50mb

        五、結(jié)論

        在本文中,我們介紹了需要使用最新的 JVM 來獲取在容器中默認(rèn)內(nèi)存設(shè)置。

        然后,研究了在自定義容器映像中設(shè)置 -Xms 和 -Xmx 的最佳實(shí)踐, 以及如何使用現(xiàn)有 Java 應(yīng)用程序容器在其中設(shè)置 JVM 選項(xiàng)。

        最后,我們看到了如何利用構(gòu)建工具來管理 Java 應(yīng)用程序的容器

        鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場,版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系管理員(admin#wlmqw.com)刪除。
        (0)
        用戶投稿
        上一篇 2022年8月7日
        下一篇 2022年8月7日

        相關(guān)推薦

        聯(lián)系我們

        聯(lián)系郵箱:admin#wlmqw.com
        工作時(shí)間:周一至周五,10:30-18:30,節(jié)假日休息