容器可移植性和 Java 语言

时间:2021-04-23 11:09:12

标签: java docker kubernetes

我是 Docker 的新手,并且已经阅读了很多关于它的内容。但是当我从 Java 应用程序的角度来看它时,我不确定它在“打包依赖项”方面做了什么增值,这是他们文档中提到的重要因素之一。

Java 已经是一种可以使用 JVM 层抽象在多个操作系统上运行的语言。一次构建,随处运行并不是一个新概念。 Docker 容器确实允许我将 JRE 版本与我的应用程序代码一起发送。所以我看到了这个好处,但是我还有其他好处吗,尤其是当我的环境(主机环境)不会改变时。即我将使用 Linux 机器进行部署。

一个胖 jar 文件就像一个打包可以使用 maven build 捆绑所有依赖项一样好。我知道容器确实有助于在Kubernetes这样的平台上部署,但是如果我必须从包装问题上严格判断容器,jar包还不够​​吗?我可能仍然需要将其容器化,才能从运行轻量级进程中受益,而不是在 VM 上运行它们。

JRE 层是否在所有其他容器中重用?这类似于在我的 VM 机器上安装 JRE。盒子上的所有应用程序都将使用相同的 JRE 版本。除非,我需要为我的应用程序运行不同版本的 JRE,这是极不可能的。

3 个答案:

答案 0 :(得分:0)

JVM/JRE 不会被重用。您可能会觉得在应用服务器环境中运行会更好。与在 JSSE 上运行相比,Docker 会有更高的开销

相比之下,运行 Docker 的优势越来越小。
一些优势可能是:

  • 测试
    • 在不同的 JRE 版本上快速测试您的代码
    • 自动化测试。使用 dockerfile,您的 CI/CD 管道可以检查您的代码、编译它、启动 docker 映像、运行测试并生成 junit 格式的测试报告。
  • 拥有一致的环境(依赖注入(如 JKS、配置等)、操作系统版本、JRE 等)
  • 环境由配置决定。
    • 您不必花时间安装操作系统、JRE 等,这是您选择的源代码控制系统中的配置文件。
    • 这让灾难恢复变得更加容易
    • 迁移得到简化(部分)

在编排环境 PaaS 中运行的优势,例如仅使用 kubernetes、openshift 或类似的东西(除了基本 docker):

  • 可以进行金丝雀部署
  • 在同一台或多台机器上进行路由、扩展和负载平衡,以优化基于机器的使用情况(有些操作的 JRE 性能会滞后超过这些甜蜜点)

答案 1 :(得分:0)

<块引用>

一个胖 jar 文件就像一个包装可以捆绑所有 使用 Maven 构建依赖

它并不像它所能得到的那么好。

您的应用程序可能有一堆依赖项:Spring、Tomcat 等等。在任何企业应用程序中,最终工件的大小将由 99% 的依赖项和 1% 的代码组成。这些依赖项可能很少更改,只有在您添加某些功能或决定升级版本时才会更改,而您的代码更改非常频繁。

胖 JAR 意味着每次部署、每次推送到存储库主机(例如 Nexus)时,您都在浪费时间上传或下载每次 99% 相同的内容。这只是一个愚蠢的 zip 文件。

Docker 是一种更智能的格式。它具有层的概念,因此您可以(并鼓励)将一层用于依赖​​项,另一层用于您的代码。这意味着如果依赖层没有改变,你就不必再次部署它,或者在你的部署中再次更新它。

因此,您可以更快地构建 CI,在存储库主机中需要更少的磁盘空间,并且可以更快地安装。例如,您还可以使用这些层更轻松地验证您的假设,即只有业务代码发生了变化。

答案 2 :(得分:0)

如果你有一个使用成熟技术的工作部署系统,你绝对应该继续使用它,即使有更新和更闪亮的东西。 Java 应用服务器空间非常成熟和成熟,如果您有一个纯 JVM 应用程序和一个有效的设置,即使现在存在 Docker 容器,保持这种设置也没有错。

如您所见,Docker 映像包含一个 JVM、一个应用程序服务器、库依赖项和应用程序。如果您有多个图像,它们被正确分层,并且这些细节完全匹配,那么它们可以被共享,但也有一个非常真实的可能性,即一个图像具有稍新的 JVM 补丁版本或基本的 Linux 发行版不是另一个。总的来说,我会说 Docker 生态系统广泛地假设应用程序“仅”使用数十兆字节的磁盘或内存不会产生显着的开销;这是与经典 Java 生态系统的主要区别,在经典 Java 生态系统中,多个应用程序将在单个进程内的单个共享 JVM 上运行。

# This base image will be shared between derived images; _if_ the
# version/build matches exactly
FROM tomcat:10-jdk11

# These libraries will be shared between derived images; _if_ the
# _exact_ set of files match _exactly_, and Tomcat is also shared
COPY target/libs/*.jar /usr/local/tomcat/lib

# This jar file presumably won't be shared
COPY target/myapp.jar /usr/local/tomcat/webapps

如果您还需要将非 JVM 服务合并到整个系统中,我会开始研究容器。如果您有一个 Java 组件、一个 Node 组件和一个 Python 组件,并且它们都通过 HTTP 进行通信,那么 Docker 将使它们也都以相同的方式部署,并且哪些部分使用哪种语言并不重要。尝试留在 JVM 生态系统中(如果 Java/Kotlin/Groovy/Scala 等 JVM 原生语言不能满足您的需求,也可以使用基于 JVM 的语言实现,例如 JRuby 或 Jython)当前设置。

相关问题