dbaplus社群 2024年11月11日
K8s上应该用哪个JDK?8种JDK性能测试
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文对 Kubernetes 上常用的 JDK 实现(如 Adoptium Eclipse Temurin、Alibaba Dragonwell、Amazon Corretto 等)进行了全面比较测试,涵盖了镜像大小、启动时间、内存使用和吞吐量等关键指标。测试结果显示,不同 JDK 实现之间的性能差异并不显著,但 IBM Semeru OpenJ9 在内存占用方面表现突出,而 Eclipse Temurin 在启动速度方面略有优势。作者通过实际案例和测试数据,为开发者选择合适的 JDK 提供了参考依据,帮助他们在 Kubernetes 环境中优化应用性能。

🤔 **镜像大小对比:** 不同 JDK 实现的镜像大小差异主要源于内置 Java 工具和二进制文件数量,Azul Zulu 镜像最小(约 271MB),Oracle JDK 镜像最大(约 446MB)。

⏱️ **启动时间测试:** 各 JDK 实现的启动时间差异不大,Eclipse Temurin 和 Oracle OpenJDK 启动速度最快,平均启动时间约为 7.2 秒,IBM Semeru OpenJ9 启动速度最慢,平均启动时间约为 9.05 秒。

🚀 **吞吐量测试:** 在模拟 5 和 10 个虚拟用户的负载测试中,各 JDK 实现的吞吐量差异也不大,BellSoft Liberica 和 Amazon Corretto 在 5 用户测试中表现较好,Eclipse Temurin 在 10 用户测试中表现较好。

🗄️ **内存使用对比:** IBM Semeru OpenJ9 在内存使用方面表现最佳,约为 135MB,其他 JDK 实现的内存使用量在 210-230MB 之间。

📊 **测试环境:** 测试环境为 MacBook Pro、macOS Ventura 13.1、Docker Desktop 上的 Kubernetes v1.25.2,使用 Java 17 编译应用程序,并使用 k6 工具进行负载测试。

piotr.minkowski 2024-11-10 08:01 广东

我们将比较所有最受欢迎的替代品,这下总能做出选择了吧!


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



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


如果您已经使用 Dockerfile 构建了镜像,那么您可能使用的是来自 Docker Hub 的官方 OpenJDK 基础镜像。然而,目前镜像网站上的公告称它已被正式弃用,所有用户都应该找到合适的替代品。


https://hub.docker.com/_/openjdk



在本文中,我们将比较所有最受欢迎的替代品,希望它能帮助您做出一个好的选择!


测试环境


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



我们将使用 Java 17 进行应用程序编译。为了运行负载测试,我将利用 k6 工具。https://k6.io/


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



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


让我们看一下 Deployment YAML 清单。它向 Mongo 数据库注入凭据并将内存限制设置为 1G:


apiVersion: apps/v1kind: Deploymentmetadata:  name: sample-spring-boot-on-kubernetes-deploymentspec:  selector:    matchLabels:      app: sample-spring-boot-on-kubernetes  template:    metadata:      labels:        app: sample-spring-boot-on-kubernetes    spec:      containers:      - name: sample-spring-boot-on-kubernetes        image: piomin/sample-spring-boot-on-kubernetes        ports:        - containerPort: 8080        env:          - name: MONGO_DATABASE            valueFrom:              configMapKeyRef:                name: mongodb                key: database-name          - name: MONGO_USERNAME            valueFrom:              secretKeyRef:                name: mongodb                key: database-user          - name: MONGO_PASSWORD            valueFrom:              secretKeyRef:                name: mongodb                key: database-password          - name: MONGO_URL            value: mongodb        readinessProbe:          httpGet:            port: 8080            path: /readiness            scheme: HTTP          timeoutSeconds: 1          periodSeconds: 10          successThreshold: 1          failureThreshold: 3        resources:          limits:            memory: 1024Mi


源代码和镜像


如果您想自己尝试,可以随时查看我的源代码。为此,您需要克隆我的 GitHub 存储库。您还可以在我的 Docker Hub 存储库中找到所有镜像piomin/sample-spring-boot-on-kubernetes。



Spring Boot 应用程序公开了几个端点,但我将测试POST /persons用于将数据插入 Mongo 的端点。在与 Mongo 的集成中,我使用了 Spring Data MongoDB 项目及其 CRUD 存储库模式。


// controller@RestController@RequestMapping("/persons")public class PersonController {
private PersonRepository repository;
PersonController(PersonRepository repository) { this.repository = repository; }
@PostMapping public Person add(@RequestBody Person person) { return repository.save(person); } // other endpoints implementation}

// repository
public interface PersonRepository extends CrudRepository<Person, String> {
Set<Person> findByFirstNameAndLastName(String firstName, String lastName); Set<Person> findByAge(int age); Set<Person> findByAgeGreaterThan(int age);
}


镜像的大小


镜像的大小是最简单的测量选项。如果您想检查镜像中到底有什么,您可以使用dive工具。不同 JVM 实现之间的大小差异是由内部包含的 Java 工具和二进制文件的数量造成的。从我的角度来看,尺寸越小越好。我宁愿不使用镜像内部的任何东西,只要能成功运行应用程序。无论如何,这是对镜像:piomin/sample-spring-boot-on-kubernetes:oracle 执行 dive 命令后 Oracle JDK 应用程序的内容。如您所见,JDK 占据了大部分空间。



另一方面,我们可以分析最小的镜像。我认为这解释了镜像大小的差异,因为 Zulu 包含 JRE,而不是整个 JDK。



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



让我们想象一下第一个结果。我认为它很好地显示了哪个镜像包含 JDK 和哪个 JRE。



启动时间


老实说,测量启动时间不是很容易,因为供应商之间的差异并不大。此外,同一提供商的后续结果可能会有很大差异。例如,在第一次尝试时,应用程序在 5.8 秒后启动,而在 pod 重启后 8.4 秒。我的方法很简单。我为每个 JDK 提供程序重启了几次应用程序,以测量平均启动时间和系列中最快的启动时间。然后我再次重复相同的练习以验证结果是否可重复。相应厂商之间的第一系列和第二系列启动时间的比例相似。事实上,最快和最慢的平均启动时间之间的差别并不大。我得到的最佳结果是:Eclipse Temurin (7.2s) 和最差结果是:IBM Semeru OpenJ9 (9.05s) 。


让我们看看完整的结果列表。它显示应用程序从最快的开始的平均启动时间。



这是我们结果的图形表示。供应商之间的差异有时是表面上的。也许,如果同样的测试从头再来一次,结果会大不相同。



正如我之前提到的,我还测量了最快的尝试。这次最好的前 3 名是 Eclipse Temurin、Amazon Corretto 和 BellSoft Liberica。



内存


我正在通过模拟 10 个用户连续发送请求的测试来测量应用程序在重负载下的内存使用情况。它在应用程序级别为我提供了非常大的吞吐量:每秒大约 500 个请求。结果符合预期。除了使用 OpenJ9 JVM 的 IBM Semeru 之外,几乎所有供应商的内存使用情况都非常相似。理论上,OpenJ9 也应该有更好的启动时间。但是,就我而言,显着差异仅在于内存占用量。IBM Semeru 的内存使用量约为 135MB,而其他供应商的内存使用量在 210-230MB 范围内变化。



这是我们结果的图形可视化:



吞吐量


为了为应用程序产生大量传入流量,我使用了k6工具。它允许我们用 JavaScript 创建测试。下面测试的实现。它使用POST /persons JSON 格式的输入数据调用 HTTP 端点。然后它验证请求是否已在服务器端成功处理。


import http from 'k6/http';import { check } from 'k6';
export default function () {
const payload = JSON.stringify({ firstName: 'aaa', lastName: 'bbb', age: 50, gender: 'MALE' });
const params = { headers: { 'Content-Type': 'application/json', }, };
const res = http.post(`http://localhost:8080/persons`, payload, params);
check(res, { 'is status 200': (res) => res.status === 200, 'body size is > 0': (r) => r.body.length > 0, });}

这是k6运行测试的命令。可以定义并发虚拟用户的持续时间和数量。第一步,我模拟 5 个虚拟用户:


$ k6 run -d 90s -u 5 load-tests.js


然后,我对每个供应商的 10 个虚拟用户运行两次测试。


$ k6 run -d 90s -u 10 load-tests.js


以下是执行k6测试后打印的示例结果:



我根据 JDK 供应商重复了这个练习。以下是 5 个虚拟用户的吞吐量结果:



以下是 10 个虚拟用户的吞吐量结果:



总结


在多次重复负载测试后,我必须承认所有 JDK 供应商之间的性能没有显着差异。可能我运行的测试越多,不同供应商之间的结果就会更加相似。


作者丨piotr.minkowski   

来源丨网址:https://piotrminkowski.com/2023/02/17/which-jdk-to-choose-on-kubernetes/

dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn


活动推荐


为了和大家一起探索AI相关技术在大数据、数据资产管理、数据库、运维等领域的最佳落地方式,挖掘由此激发的软件发展和技术进步,第九届DAMS中国数据智能管理峰会将于2024年11月29日在上海举办,携手一众产学研界技术领跑单位,带来新思路、重实践、可落地的全日干货盛宴。早鸟优惠,码上报名↓


跳转微信打开

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

JDK Kubernetes 性能测试 JVM 镜像大小
相关文章