在 Kubernetes 中选择哪个 JDK?


在本文中,我们将对运行在 Kubernetes 上的应用程序的几种最流行的 JDK 实现进行性能比较。

这次我将通过多次重复进行非常准确的比较以获得可重现的结果。我将测试以下 JVM 实现:

  • Adoptium Eclipse Temurin
  • 阿里巴巴龙井Dragonwell
  • 亚马逊 Corretto
  • Azul Zulu
  • BellSoft Liberica
  • IBM Semeru OpenJ9
  • 甲骨文JDK
  • 微软OpenJDK

对于所有测试,我将使用 Paketo Java buildpack。我们可以使用 Paketo 轻松地在多个 JVM 实现之间切换。我将测试一个简单的 Spring Boot 3 应用程序,它使用 Spring Data 与 Mongo 数据库进行交互。

测试环境
在我们运行测试之前,拥有一个预配置的环境很重要。我将在本地运行所有测试。为了构建图像,我将使用 Paketo Buildpacks。以下是我的环境的一些细节:

  1. 机器:MacBook Pro 32G RAM 英特尔 
  2. 操作系统:macOS Ventura 13.1
  3. Docker 桌面上的 Kubernetes (v1.25.2):14G RAM + 4vCPU

我们将使用 Java 17 进行应用程序编译。为了运行负载测试,我将利用k6工具。我们的应用程序是用 Spring Boot 编写的。它连接到运行在同一 Kubernetes 实例上的 Mongo 数据库。每次我测试一个新的 JVM 提供程序时,我都会删除以前版本的应用程序和数据库。然后我再次部署新的完整配置。我们将测量以下参数:

  1. 应用程序启动时间(最佳  
  2. 结果和平均值)——我们将直接从 Spring Boot 日志中读取它 
  3. 吞吐量——使用 k6,我们将模拟 5 和 10 个虚拟用户。它将测量处理请求的数量 
  4. 图片大小
  5. Pod 在负载测试期间消耗的 RAM 内存。基本上,我们将执行 kubectl top pod 命令

我们还将容器的内存限制设置为 1G。在我们的负载测试中,应用程序会将数据插入 Mongo 数据库。它公开了在测试期间调用的 REST 端点。为了尽可能准确地测量启动时间,我将多次重启该应用程序。

源代码:GitHub 存储库

镜像大小
从最小图像到最大图像排序的结果。

  • Azul Zulu:271MB
  • IBM Semeru OpenJ9:275MB
  • Eclipse Temurin:286MB
  • BellSoft Liberica:286MB
  • 甲骨文 OpenJDK:446MB
  • 阿里巴巴龙井:459MB
  • 微软 OpenJDK:461MB
  • 亚马逊 Corretto:463MB

启动时间

从最快的开始的平均启动时间:

  • Eclipse Temurin:7.20s
  • 甲骨文 OpenJDK:7.22 秒
  • 亚马逊 Corretto:7.27 秒
  • BellSoft Liberica:7.44s
  • 甲骨文 OpenJDK:7.77 秒
  • 阿里巴巴龙井:8.03s
  • 微软 OpenJDK:8.18 秒
  • IBM Semeru OpenJ9:9.05 秒

内存

  • IBM Semero OpenJ9:135M
  • 甲骨文 OpenJDK:211M
  • Azul Zulu:215M
  • 阿里巴巴龙井:216M
  • BellSoft Liberica:219M
  • 微软 OpenJDK:219M
  • 亚马逊 Corretto:220M
  • Eclipse Temurin:230M

吞吐量

  • BellSoft Liberica:451req/s
  • 亚马逊 Corretto:433req/s
  • IBM Semeru OpenJ9:432req/s
  • 甲骨文 OpenJDK:420 请求/秒
  • 微软 OpenJDK:418req/s
  • 蔚蓝祖鲁:414req/s
  • Eclipse Temurin:407req/s
  • 阿里巴巴龙井:405req/s


最后的想法
在多次重复负载测试后,我必须承认所有 JDK 供应商之间的性能没有显着差异。我们使用相同的 JVM 设置进行测试(由 Paketo Buildpack 设置)。可能我运行的测试越多,不同供应商之间的结果就会更加相似。