我是 Docker 的新手,并且已经阅读了很多关于它的内容。但是当我从 Java 应用程序的角度来看它时,我不确定它在“打包依赖项”方面做了什么增值,这是他们文档中提到的重要因素之一。
Java 已经是一种可以使用 JVM 层抽象在多个操作系统上运行的语言。一次构建,随处运行并不是一个新概念。 Docker 容器确实允许我将 JRE 版本与我的应用程序代码一起发送。所以我看到了这个好处,但是我还有其他好处吗,尤其是当我的环境(主机环境)不会改变时。即我将使用 Linux 机器进行部署。
一个胖 jar 文件就像一个打包可以使用 maven build 捆绑所有依赖项一样好。我知道容器确实有助于在Kubernetes这样的平台上部署,但是如果我必须从包装问题上严格判断容器,jar包还不够吗?我可能仍然需要将其容器化,才能从运行轻量级进程中受益,而不是在 VM 上运行它们。
JRE 层是否在所有其他容器中重用?这类似于在我的 VM 机器上安装 JRE。盒子上的所有应用程序都将使用相同的 JRE 版本。除非,我需要为我的应用程序运行不同版本的 JRE,这是极不可能的。
答案 0 :(得分:0)
JVM/JRE 不会被重用。您可能会觉得在应用服务器环境中运行会更好。与在 JSSE 上运行相比,Docker 会有更高的开销
相比之下,仅运行 Docker 的优势越来越小。
一些优势可能是:
在编排环境 PaaS 中运行的优势,例如仅使用 kubernetes、openshift 或类似的东西(除了基本 docker):
答案 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)当前设置。