Docker容器与JVM比较

Java 的一大卖点是 Java 虚拟机带来的可移植性。 但是,由于在 [Docker] 容器中捆绑后端服务已成为常见做法,那么与本机编译语言相比,Java 有哪些优势呢?

Docker 容器
Docker 容器是一种轻量级的虚拟化技术,它将应用程序和其依赖项打包到一个可移植的镜像中。Docker 容器可以运行在任何支持 Docker 的操作系统上,这使得它们非常适合在云环境中部署应用程序。
Docker 容器的优点

  • 轻量级:Docker 容器的大小通常只有几百 MB,这使得它们非常适合在资源有限的环境中使用。
  • 可移植:Docker 容器可以运行在任何支持 Docker 的操作系统上,这使得它们非常适合在云环境中部署应用程序。
  • 隔离:Docker 容器将应用程序与其所在环境隔离开来,这有助于提高安全性和可靠性。

Docker 容器的缺点
  • 平台相关性:Docker 容器通常是平台相关的,这意味着它们不能直接在不同平台上运行。
  • 安全性:Docker 容器的安全性取决于容器镜像的安全性,因此需要对容器镜像进行仔细审查。

JVM
JVM 是一种虚拟机,它允许 Java 程序在任何平台上运行。JVM 将 Java 字节码转换为机器码,这使得 Java 程序可以运行在任何支持 JVM 的操作系统上。
JVM 的优点

  • 平台无关性:Java 程序可以运行在任何支持 JVM 的操作系统上。
  • 安全性:JVM 提供了内置的安全功能,如类加载器和垃圾回收器。
  • 可移植性:Java 代码可以很容易地从一个平台移植到另一个平台。

JVM 的缺点
  • 性能损失:JVM 会增加 Java 程序的运行时间,这称为“Java 开销”。
  • 内存占用:JVM 需要占用一定的内存,这可能会影响 Java 程序的性能。

Docker容器和Java虚拟机(JVM)是两个不同的概念,但它们通常在应用程序部署和运行时联系在一起。
下面是它们之间的一些比较:

  1. 虚拟化层次:
    • Docker容器:Docker容器是一种轻量级的虚拟化技术,允许将应用程序及其依赖项打包到一个可移植的容器中。容器共享主机的内核,因此启动速度快,占用的资源较少。
    • JVM:Java虚拟机是一个在主机上运行Java字节码的虚拟机。它提供了对Java程序的抽象,使得Java应用程序可以在不同的平台上运行。
  • 环境隔离:
    • Docker容器:容器提供了隔离的文件系统、网络和进程空间。每个容器都有自己的文件系统快照,独立于主机和其他容器。
    • JVM:虽然JVM提供了一些隔离性,但它主要是为Java应用程序提供了一个独立的运行时环境,而不是全面的容器化解决方案。
  • 资源占用:
    • Docker容器:容器共享主机的内核,因此它们相对较轻量,占用的资源较少。每个容器都运行在一个独立的进程中。
    • JVM:Java应用程序运行在JVM中,它通常需要一定的内存和其他资源。虽然JVM可以通过调整参数进行优化,但它可能在某些情况下占用较多的资源。
  • 可移植性:
    • Docker容器:容器提供了一个可移植的运行时环境,使应用程序在不同的环境中保持一致。
    • JVM:Java应用程序在任何支持Java虚拟机的地方都可以运行,但并不提供与Docker容器相似的完整环境隔离。
  • 部署和维护:
    • Docker容器:容器可以轻松地打包和部署,也更容易进行水平扩展。Docker提供了丰富的工具和生态系统来管理容器的生命周期。
    • JVM:Java应用程序的部署通常涉及将Java代码和相关的依赖打包成JAR文件或WAR文件,并在目标环境中安装Java虚拟机。

    总体而言,Docker容器和JVM有不同的应用场景。Docker容器更适用于构建和部署复杂的分布式应用程序,而JVM更专注于提供Java应用程序的运行时环境。

    在一些情况下,它们可以结合使用,例如在Docker容器中运行Java应用程序。

    为什么在容器内使用 Java?
    docker 容器的优势和在 jvm 上运行 java 的优势基本上是两个不同的概念。

    Docker 容器
    Docker 容器主要用于隔离环境中安装的应用程序版本、网络和其他更高级别的配置,同时允许容器以比完整虚拟机更高效的方式更轻松地共享系统资源和底层 Linux 内核。

    Docker 并不是对其他架构的模拟,因此你仍然无法使用 docker 在 jvm 尚未实现的架构上毫不费力地运行程序。

    其中一个有用的例子是,管理两个需要不同 jre 版本的独立 java 应用程序更容易。在裸机上管理这两个版本可能会很麻烦。通过 Docker,您只需花费极少的精力就能让这两个版本并排运行。

    jvm
    jvm 可以在多种不同的架构上运行,这就是可移植性的来源。jvm 对架构/编译器特定的基元大小、操作系统特定的交互等进行了抽象,因此编译后的字节码可以在 jvm 运行的任何架构/操作系统上运行。Docker 在 linux 上运行,通过在虚拟机中运行 linux 支持其他操作系统。

    简而言之,Docker 用于提供隔离配置,以解决 "它能在我的电脑上运行 "的问题。为 jvm 进行编译则解决了学习底层操作系统、架构等复杂知识的问题。

    需要注意的是,Java 是一种语言而非运行时。它可以编译成 jvm 字节码,然后在 jvm 中运行。安卓系统不使用 jvm,而是通过几个字节码编译成本地可执行文件。

    其他技术(如 GraalVM)允许你将 java 编译成桌面本地可执行文件。当然,Java 并不局限于 jvm。

    说白了:Docker统一了linux运行的外部标准,而JVM统一了跨win和linux标准,Docker + JVM能够真正跨win和linux运行,Docker等于在JVM和操作系统之间再增加了一层,虽然复杂了,这也是win、linux和MacOS长期三国之战中用户为了统一它们的运行环境,如同:

    • 欧盟类似欧洲的容器,而每个欧洲人可以选择欧盟统一框架下生活,也可以选择德国本地化很严重的方式生活,
    • 选择Docker如同在广州、深圳、上海说普通话,至少在普通话这个容器下,你生活的顺利,而这些城市也有本地方言,这样你没有必要一开始就要学本地话才能在本地生活。