zoukankan      html  css  js  c++  java
  • 原创 Spring Boot 2.3 新特性分层JAR

    背景

    在我们实际生产容器化部署过程中,往往会遇到 Docker 镜像很大,部署发布很慢的情况

    影响 docker 镜像大小的因素,主要有以下三个方面:

      1. 基础镜像的大小 。尽量选择 aphine 作为基础镜像 减少操作系统内置软件
      1. Dockerfile 指令层数。 这就要求我们优化 Dockerfile 能合并在一行的尽量合并等
      1. 应用 jar 的大小。这是今天要分享的重点内容

    helloworld 镜像

    我们先来基于 spring boot 2.3.0 构建一个最简单的 web helloworld,然后构建镜像。

    FROM adoptopenjdk:11-jre-hotspot as builder
    WORKDIR application
    ARG JAR_FILE=target/*.jar
    COPY ${JAR_FILE} application.jar
    ENTRYPOINT ["java", "-jar application.jar"]
    
    docker build --build-arg JAR_FILE=./demo-layer-0.0.1-SNAPSHOT.jar  . -t demo:v1.0
    

    查看镜像分层信息

    我们通过 docker inspect demo:v1.0 来看下此镜像的每层的散列值

    // demo:v1.0 版本镜像分层信息摘要
    "Layers": [
        "sha256:b7f7d2967507ba709dbd1dd0426a5b0cdbe1ff936c131f8958c8d0f910eea19e",
        "sha256:a6ebef4a95c345c844c2bf43ffda8e36dd6e053887dd6e283ad616dcc2376be6",
        "sha256:838a37a24627f72df512926fc846dd97c93781cf145690516e23335cc0c27794",
        "sha256:28ba7458d04b8551ff45d2e17dc2abb768bf6ed1a46bb262f26a24d21d8d7233",
        "sha256:55c91231ac46fdd63c3cf84b88b11f8a04c1870482dcff033029a601bc50e1ab",
        "sha256:9816c2d488754509f6024a267738b1e5fe33a7cd33bd25c5a9cdf6d4d7bfed1d",
        "sha256:f5fb3f91797d57a92f3f7e033398b8edd094df664db849a4950eabf2f5474535",
        "sha256:b87d2ff74819f83038ea2f89736a19cfcf99bfa080b8017d191c900a09a7524f"
    ]
    

    helloworld 升级重新构建

    我们对 helloworld 程序进行部分修改(模拟开发过程),然后重新构建镜像

    docker build --build-arg JAR_FILE=./demo-layer-0.0.1-SNAPSHOT.jar  . -t demo:v1.1
    

    此时镜像分层信息如下 docker inspect demo:v1.1

    // demo:v1.1 版本镜像分层信息摘要
    "Layers": [
        "sha256:b7f7d2967507ba709dbd1dd0426a5b0cdbe1ff936c131f8958c8d0f910eea19e",
        "sha256:a6ebef4a95c345c844c2bf43ffda8e36dd6e053887dd6e283ad616dcc2376be6",
        "sha256:838a37a24627f72df512926fc846dd97c93781cf145690516e23335cc0c27794",
        "sha256:28ba7458d04b8551ff45d2e17dc2abb768bf6ed1a46bb262f26a24d21d8d7233",
        "sha256:55c91231ac46fdd63c3cf84b88b11f8a04c1870482dcff033029a601bc50e1ab",
        "sha256:9816c2d488754509f6024a267738b1e5fe33a7cd33bd25c5a9cdf6d4d7bfed1d",
        "sha256:f5fb3f91797d57a92f3f7e033398b8edd094df664db849a4950eabf2f5474535",
        "sha256:c1b6350d545fea605e0605c4bfd7f4529cfeee3f6759750d6a5ddeb9c882fc8f"
    ]
    

    比较 v1.0、v1.1 镜像

    通过比较 v1.0 和 v1.1 版本的镜像摘要信息,我们会发现只有最后的一层发生了变化,我们通过 Dive 是一个用 Go 语言编写的 Docker 镜像分析工具 来确定一下 最后一层是做了哪些事情

    dive demo:v1.0,大家会看到是最后的 jar 不一样 导致 16M 的内容需要重新构建,当你的业务 jar 很大时,这块就是性能瓶颈

    spring boot 默认打包解密

    默认情况下,spring boot 构建出来的 jar ,解压后可以看到如下目录结构。默认会当做一个整体 ,在构建镜像时作为一个单独层,没有区分业务 classes 和 引用的第三方 jar

    META-INF/
      MANIFEST.MF
    org/
      springframework/
        boot/
          loader/
    BOOT-INF/
      classes/
      lib/
    

    layer jar

    通过上文大家就可以知道分层 jar 的思想就是把,jar 再根据规则细分,业务 class 和 三方 jar 分别对应镜像的不同层,这样改动业务代码,只需变动很少的内容 提高构建速度。

    开启分层打包

      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
          <layers>
            <enabled>true</enabled>
          </layers>
        </configuration>
      </plugin>
    

    编写支持分层 Dockerfile

    核心是通过 spring boot 提供的 layertools 工具,将 jar 进行拆分 然后通过 COPY 指令去分别加载

    FROM adoptopenjdk:11-jre-hotspot as builder
    WORKDIR application
    ARG JAR_FILE=target/*.jar
    COPY ${JAR_FILE} application.jar
    RUN java -Djarmode=layertools -jar application.jar extract
    FROM adoptopenjdk:11-jre-hotspot
    WORKDIR application
    COPY --from=builder application/dependencies/ ./
    COPY --from=builder application/spring-boot-loader/ ./
    COPY --from=builder application/snapshot-dependencies/ ./
    COPY --from=builder application/application/ ./
    ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]
    

    构建新镜像并查看分层信息

    docker build --build-arg JAR_FILE=./demo-layer-0.0.1-SNAPSHOT.jar  . -t demo:v2.0
    
    "Layers": [
        "sha256:b7f7d2967507ba709dbd1dd0426a5b0cdbe1ff936c131f8958c8d0f910eea19e",
        "sha256:a6ebef4a95c345c844c2bf43ffda8e36dd6e053887dd6e283ad616dcc2376be6",
        "sha256:838a37a24627f72df512926fc846dd97c93781cf145690516e23335cc0c27794",
        "sha256:28ba7458d04b8551ff45d2e17dc2abb768bf6ed1a46bb262f26a24d21d8d7233",
        "sha256:55c91231ac46fdd63c3cf84b88b11f8a04c1870482dcff033029a601bc50e1ab",
        "sha256:9816c2d488754509f6024a267738b1e5fe33a7cd33bd25c5a9cdf6d4d7bfed1d",
        "sha256:f5fb3f91797d57a92f3f7e033398b8edd094df664db849a4950eabf2f5474535",
        "sha256:06fe18cf8ae7384f120f2c6a3a33b31999dd0460cf1edae45e8f13adeab35942",
        "sha256:16cf814564b8a667fcc9f07314b6084cbef8dc8c0a6565c7a2d91d74faf7e7de",
        "sha256:94be40f716016b68cdd6b99d2cb8154acf8475c3a170a898a22f95a8ef40ffd3",
        "sha256:427d87d6a5fe6da13cb4233939c3a1ff920bc6b4d2f14b5d78af7aef98fda7de"
    ]
    

    修改代码部分业务代码,重新构建

    docker build --build-arg JAR_FILE=./demo-layer-0.0.1-SNAPSHOT.jar  . -t demo:v2.1
    
    "Layers": [
        "sha256:b7f7d2967507ba709dbd1dd0426a5b0cdbe1ff936c131f8958c8d0f910eea19e",
        "sha256:a6ebef4a95c345c844c2bf43ffda8e36dd6e053887dd6e283ad616dcc2376be6",
        "sha256:838a37a24627f72df512926fc846dd97c93781cf145690516e23335cc0c27794",
        "sha256:28ba7458d04b8551ff45d2e17dc2abb768bf6ed1a46bb262f26a24d21d8d7233",
        "sha256:55c91231ac46fdd63c3cf84b88b11f8a04c1870482dcff033029a601bc50e1ab",
        "sha256:9816c2d488754509f6024a267738b1e5fe33a7cd33bd25c5a9cdf6d4d7bfed1d",
        "sha256:f5fb3f91797d57a92f3f7e033398b8edd094df664db849a4950eabf2f5474535",
        "sha256:06fe18cf8ae7384f120f2c6a3a33b31999dd0460cf1edae45e8f13adeab35942",
        "sha256:16cf814564b8a667fcc9f07314b6084cbef8dc8c0a6565c7a2d91d74faf7e7de",
        "sha256:94be40f716016b68cdd6b99d2cb8154acf8475c3a170a898a22f95a8ef40ffd3",
        "sha256:8a20c60d361696a4e480fb6fbe1daf8b88bc54c579a98e209da1fb76e25de5aa"
    ]
    

    查看区别层镜像

    最后一层变动大小为 5KB

    总结

    项目推荐: Spring Cloud 、Spring Security OAuth2的RBAC权限管理系统 欢迎关注

  • 相关阅读:
    AFNetworking 3.0中调用[AFHTTPSessionManager manager]方法导致内存泄漏的解决办法
    UITableView自动计算cell高度并缓存
    iOS 10 应用内跳转到系统设置
    iOS 系统通知
    UITableViewDataSource TableView數據源協議
    HADOOP操作权限问题
    Echarts简单图表
    hadoop常见错误解决方法
    sqoop安装与简单实用
    hive的内置函数和自定义函数
  • 原文地址:https://www.cnblogs.com/leng-leng/p/13064085.html
Copyright © 2011-2022 走看看