【SpringBoot系列】SpringBoot应用程序容器化及容器优化

简介: 【4月更文挑战第4天】SpringBoot应用程序容器化及容器大小优化

[toc]


前言

在我之前的文章中 我们学习了如何创建一个简单的 Spring Boot 应用程序,我们还学习了如何将其打包为 jar 文件并在本地运行。但是,目前在生产环境中,docker 被广泛采用。在这篇文章中,我们将看到如何容器化我们的 Spring Boot 应用程序。

一、构建Dockerfile

FROM ubuntu:18.04
ARG MAVEN_VERSION=3.8.5
ARG BASE_URL=https://downloads.apache.org/maven/maven-3/${MAVEN_VERSION}/binaries
# Install Java
RUN apt-get update \
    && apt-get install -y curl\
    && apt-get install -y openjdk-17-jdk ca-certificates-java\
    && apt-get clean \
    && update-ca-certificates -f
ENV JAVA_HOME /usr/lib/jvm/java-17-openjdk-amd64
RUN export JAVA_HOME
# Install Maven
RUN  curl -OLs ${BASE_URL}/apache-maven-${MAVEN_VERSION}-bin.tar.gz \
 && tar -xzf apache-maven-${MAVEN_VERSION}-bin.tar.gz -C /usr/local/ \
 && ln -s /usr/local/apache-maven-${MAVEN_VERSION}/bin/mvn /usr/bin/mvn \
 && rm -f /tmp/apache-maven-${MAVEN_VERSION}-bin.tar.gz

COPY . .

RUN mvn clean package
COPY target/*.jar app.jar
CMD ["java","-jar","app.jar"]

我们通过运行 docker build -t spring-first-web-app:1.0.0 创建一个新映像,然后通过运行 docker run spring-first-web-app:1.0.0 来运行我们的应用程序。
目前为止,一切都好。我们看到应用程序正在启动。
image.png

二、优化一

上图虽然工作正常,但我们可以看到一些问题,第一个是大小。如果我们运行 docker 镜像 spring-first-web-app:1.0.0,我们会看到镜像大约是 1 GB
image.png

对于一个基本上什么都没有的应用程序来说,这是巨大的。我们可以做的第一件事是移动到较小的基础映像。

FROM openjdk:17
ARG MAVEN_VERSION=3.8.5
ARG BASE_URL=https://downloads.apache.org/maven/maven-3/${MAVEN_VERSION}/binaries

RUN  curl -OLs ${BASE_URL}/apache-maven-${MAVEN_VERSION}-bin.tar.gz \
 && tar -xzf apache-maven-${MAVEN_VERSION}-bin.tar.gz -C /usr/local/ \
 && ln -s /usr/local/apache-maven-${MAVEN_VERSION}/bin/mvn /usr/bin/mvn \
 && rm -f /tmp/apache-maven-${MAVEN_VERSION}-bin.tar.gz

COPY . .

RUN mvn clean package
COPY target/*.jar app.jar
CMD ["java","-jar","app.jar"]

我们移到了一个新的基础映像。OpenJDK 是 Java 的开源分支,提供了许多基本映像。这些映像的优点是我们不需要手动安装Java,而且这些映像会不时获得安全补丁和更新。因此,有一项任务不在我们的清单上。现在,当我们构建映像时,我们可以看到大小减少到大约 600MB
image.png

三、优化二

我们能做得更好吗?如果我们仔细遵循,我们有两个阶段,在第一阶段我们下载 maven 并编译我们的 java 源代码。在第二阶段,我们运行打包的应用程序。一旦我们有了打包的应用程序,我们就不再需要 mvn 和 JDK 了。我们所需要的只是一个 JRE。
多阶段 docker 构建的想法来了。在多阶段 docker 构建中,我们可以从前几个阶段中挑选工件,并丢弃所有前几个阶段中的任何内容。
以下是我们如何做到这一点。

FROM eclipse-temurin:17 as build
ARG MAVEN_VERSION=3.8.5
ARG BASE_URL=https://downloads.apache.org/maven/maven-3/${MAVEN_VERSION}/binaries

RUN  curl -OLs ${BASE_URL}/apache-maven-${MAVEN_VERSION}-bin.tar.gz \
 && tar -xzf apache-maven-${MAVEN_VERSION}-bin.tar.gz -C /usr/local/ \
 && ln -s /usr/local/apache-maven-${MAVEN_VERSION}/bin/mvn /usr/bin/mvn \
 && rm -f /tmp/apache-maven-${MAVEN_VERSION}-bin.tar.gz

COPY . .

RUN mvn clean package
COPY target/*.jar app.jar

FROM eclipse-temurin:17-jre-alpine as production
COPY --from=build app.jar .
CMD ["java","-jar","app.jar"]

在上面的 docker 文件中,我们有两个阶段。第一阶段构建是构建阶段。在构建阶段,我们下载 maven 并编译我们的 java 源代码。在第二阶段生产中,我们运行打包的应用程序。了解有关多阶段 docker 构建的更多信息 https://docs.docker.com/develop/develop-images/multistage-build/ 。让我们看看现在 docker 大小是多少:
image.png

我们看到尺寸大幅减小。原因是,在生产阶段,我想要一个仅限 JRE 的镜像。但是,对于较新版本的 Java,upsteam OpenJDK 项目不再生成 JRE,因此没有仅 JRE 映像。github 上有很多关于这个问题的讨论。例如,请参见 https://github.com/docker-library/openjdk/issues/468 。还有另一个提供商 Adoptium(以前称为 AdoptopenJDK),在他们的 Java 版本下,称为 Temurin,它仍然提供 JRE 镜像。你可以找到一篇关于他们的决定的好文章 https://blog.adoptium.net/2021/12/eclipse-temurin-jres-are-back/.因此,我开始使用temurin。

四、更多优化

  • Spring 分层镜像
  • Spring Buildpack

Spring buildpack 支持为 Spring 应用程序创建映像,而无需编写 Dockerfile 。在后面的文章中,我将解释如何创建弹簧分层图像。

小节

这就是这篇文章的内容,我们现在知道如何创建最低限度的Spring应用程序以及如何创建镜像,以及如何进行镜像大小的优化。

目录
相关文章
|
6天前
|
Java
springboot如何确定当前应用程序是响应式的还是非响应式的
springboot如何确定当前应用程序是响应式的还是非响应式的
springboot如何确定当前应用程序是响应式的还是非响应式的
|
6天前
|
Java 测试技术 开发工具
ApplicationArguments读取应用程序参数并注入到IOC容器
ApplicationArguments读取应用程序参数并注入到IOC容器
ApplicationArguments读取应用程序参数并注入到IOC容器
|
6天前
|
运维 Kubernetes 测试技术
容器技术:优化软件测试流程的利器
本文介绍了容器技术的概念、优势和历史发展,对比了容器与虚拟机的区别,并提及了Docker和Kubernetes等常见容器技术。容器作为轻量级虚拟化工具,提供高效、灵活的应用部署方式,广泛应用于软件开发、云计算和微服务架构。随着技术演进,容器将在边缘计算、人工智能等领域发挥更大作用,推动行业变革。
16 3
|
6天前
|
存储 虚拟化 数据中心
|
6天前
|
缓存 关系型数据库 数据库
【Docker 专栏】Docker 与容器化数据库的集成与优化
【5月更文挑战第9天】本文探讨了Docker与容器化数据库集成的优势,如快速部署、环境一致性、资源隔离和可扩展性,并列举了常见容器化数据库(如MySQL、PostgreSQL和MongoDB)。讨论了集成方法、注意事项、优化策略,包括资源调整、缓存优化和监控告警。此外,强调了数据备份、恢复测试及性能评估的重要性。未来,随着技术发展,二者的集成将更紧密,为数据管理带来更多可能性。掌握此技术将应对数字化时代的机遇与挑战。
【Docker 专栏】Docker 与容器化数据库的集成与优化
|
6天前
|
存储 Java 应用服务中间件
Springboot项目打war包部署到外置tomcat容器【详解版】
该文介绍了将Spring Boot应用改为war包并在外部Tomcat中部署的步骤:1) 修改pom.xml打包方式为war;2) 排除内置Tomcat依赖;3) 创建`ServletInitializer`类继承`SpringBootServletInitializer`;4) build部分需指定`finalName`;5) 使用`mvn clean package`打包,将war包放入外部Tomcat的webapps目录,通过startup脚本启动Tomcat并访问应用。注意,应用访问路径和静态资源引用需包含war包名。
|
6天前
|
Java 应用服务中间件 Maven
【SpringBoot系列】第一课:构建一个简单的SpringBoot应用程序
【4月更文挑战第3天】构建第一个SpringBoot应用程序
30 1
|
6天前
|
Java 应用服务中间件 API
【SpringBoot技术专题】「开发实战系列」Undertow web容器的入门实战及调优方案精讲
【SpringBoot技术专题】「开发实战系列」Undertow web容器的入门实战及调优方案精讲
52 0
|
6天前
|
存储 前端开发 Java
springboot中的第二个IOC容器BootstrapContext
springboot中的第二个IOC容器BootstrapContext
springboot中的第二个IOC容器BootstrapContext
|
22小时前
|
Prometheus 监控 Cloud Native
构建高效稳定的Docker容器监控体系
【5月更文挑战第20天】 在微服务架构日益普及的今天,Docker作为其重要的实现技术之一,承载着大量应用的运行。然而,随之而来的是对于容器健康状态、资源使用情况以及性能指标的监控需求急剧增加。本文旨在探讨构建一个高效且稳定的Docker容器监控体系,不仅涵盖了监控工具的选择与配置,还详细阐述了监控数据的分析与处理流程。通过精心设计的监控策略和实时响应机制,我们能够确保系统的稳定性,并及时发现及处理潜在的问题。

热门文章

最新文章