哪个应用程序容器更适合 Docker 容器?

Which application container is better for Docker container?

我们未来的架构是朝着docker/微服务的方向发展。目前我们正在使用 JBoss EAP 6.4(有可能升级到 EAP 7)和 Tomcat。

根据我的说法,JEE 容器对于微服务环境而言太重(速度慢、内存更多、维护成本更高等)。但是,有人告诉我 EAP 7 非常快且重量轻,可用于开发微服务。在决定 docker/microservices 是 EAP 7 还是 Tomcat 8 时,您有何意见?会考虑成本和速度。

EAP7 vs Tomcat 8 是一个古老的问题,已多次回答 here, here and here

Tomcat 只是一个 Web 容器,而 EAP7 是一个应用程序服务器,提供所有 Java EE 7 特性,例如持久性、消息传递、Web 服务、安全性、管理等。EAP7 来了在两个配置文件中 - Web 配置文件和完整配置文件。 Web Profile 是更精简的版本,仅包含构建 Web 应用程序通常所需的相关实现。如您所料,完整配置文件包含平台的全部荣耀。因此,使用 EAP 7 Web 配置文件将帮助您大大减少膨胀。

使用 Tomcat,您必须使用 Spring 之类的东西来带来等效的功能,并将所有相关的 JAR 与您的应用程序打包在一起。

当您开始一个全新的项目并且手头有 Java EE 或 Spring 资源时,这些讨论通常会很有帮助。以下是您可能考虑使用 EAP7 的原因:

  • 您已经在使用 EAP 6.4。迁移到 EAP 7 将是无缝的。使用 Docker 只是一种不同的应用程序打包方式。您现有的所有监控、集群、日志记录都将继续工作。如果您要使用 Tomcat,那么您将必须学习 Spring 的做事方式。如果你有时间和资源并且愿意尝试,你也可以走那条路。但是想想你想从中得到什么?
  • EAP 7 针对容器和云部署进行了优化。特别是,它作为 OpenShift 的服务提供,因此您知道它可以在 OOTB 中使用。
  • 与 EAP 6.4 相比,EAP 7 将在延迟和吞吐量方面提供不错的性能提升。阅读 https://access.redhat.com/articles/2607521 了解更多详情。

您也可以考虑TomEE。他们提供 Java 与 Tomcat 集成的 EE 堆栈。

@Federico 推荐的另一种选择,考虑使用 WildFly Swarm。然后,您就可以真正开始自定义 Java EE 平台的哪些部分。并且您的部署模型使用的是 JAR 文件。

至于使用Docker打包,它们都提供了一个基础镜像,你需要将你的应用程序打包在其中。以下是将 Docker 图像用于微服务的几个重要注意事项:

  • Docker 图像的大小:容器可能会意外终止,或者编排框架可能决定将其重新安排在不同的主机上。更大的图像尺寸将花费更长的时间来下载。这意味着您感知到的服务启动时间对于更大的图像来说会更长。这也意味着应用程序的动态缩放需要更长的时间才能生效。
  • 镜像启动时间:镜像下载后,容器可能启动很快,但应用需要多长时间"ready"?

作为个人说明,与 Tomcat/Spring 相比,我对 Java EE 堆栈更熟悉,并且 WildFly 仍然是最喜欢的应用程序服务器。

除了使用没有那么重的传统应用程序服务器外,您还可以品尝到 Java EE 的不同风味,称为微容器。

Java EE只是一套标准。标准导致 API 规范,然后每个人都可以自由实施该规范。应用服务器 (AS) 主要是此功能的 fine-tuned 集合。那些 API 没有无缘无故地复活。这些代表项目中常用的功能。应用服务器可以看作是这些功能的 "curated set"。这种方法有很多优点——AS 有很多用户,因此随着时间的推移它得到了很好的测试。自行连接功能可能会导致错误。

无论如何,一个新时代已经到来,随着 Docker,应用程序携带了它的依赖项。在许多情况下,不再需要 full-blown 具有所有功能的应用程序服务器来为应用程序提供服务。过去,应用服务器并不确切知道部署的应用程序需要哪些服务。因此,一切都捆绑在一起。一些更具创新性的 AS,如 WildFly 仅实例化所需的服务。此外,还有 Java EE 配置文件,可以稍微简化单体应用服务器。

现在,我们通常在 Docker 中将应用程序及其依赖项(JDK、库、AS)一起发布 - 或者我们正在前往那里。因此,努力捆绑恰到好处的数量是合乎逻辑的选择。但是,它是 "big but",对 AS 功能的需求仍然是相关的。基于标准和共同努力开发通用功能仍然是个好主意。它似乎不再是将其作为一个大包分发的选项,可能会使大多数 API 处于非活动状态。这项工作有很多名称,可以是微容器、uberjar 创作者……

有Java个EE服务器,太轻了,用别的东西值得怀疑。 * Spring 引导不是基于 Java EE,在入门指南中的默认配置中,内部使用 Tomcat。

关键是,您的 Java EE 应用程序应该作为独立的 Java EE 应用程序开发。用 "just enough" 功能包装它被委托给这些微解决方案。至少在我看来,这是正确的方法。这样,您将保持与 full-blown AS 和 micro-solutions 的兼容性。包含所有依赖项的 uber-jar 可以在构建过程中或之后创建。

WildFly Swarm 或 Payara Micro 能够"scan" 应用程序,运行 仅提供所需的服务。对于 real-world 应用程序,生产中的内存占用量可低至 100 MB - 对于 real-world 应用程序。这可能就是你想要的。 Spring Boot 可以做类似的事情,如果你需要 Spring。但是,根据我的经验,Spring Boot 在内存消耗方面是 much more heavyweight and memory hungry than modern Java EE, because it obviously has Spring inside, so if you are seeking lightweigtness,尝试 Java EE,尤其是 WildFly Swarm(或纯 WildFly)和 Payara Micro。这些是我最喜欢的 AS,它们可以非常非常小。我会说 WildFly Swarm 更容易上手,Payara micro 需要更多阅读,但提供了有趣的功能。两者都可以用作包装器 - 您可以在构建阶段后将当前项目与它们一起包装,无需更改任何内容。

Payara Micro 甚至 provides Docker images 可以使用了!如您所见,Java EE 已经成熟并准备进入 Docker 土地 :)

Adam Bien 是非常好的和可靠的资源之一,例如在他的 Java EE micro/nanoservices video 中。看看。