Java微服务的优点有哪些

发布时间:2021-10-14 11:23:37 作者:iii
来源:亿速云 阅读:147

本篇内容主要讲解“Java微服务的优点有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java微服务的优点有哪些”吧!

1. 背景介绍

我们希望通过实验了解 Java 微服务在运行速度上能否达到 Go 微服务的水平。目前,软件行业普遍认为 Java 已经过于陈旧、缓慢且无聊。而 Go 则成了快速、崭新以及酷炫的代名词。真是这样吗?我们想从数据的角度看看这样的印象是否站得住脚。

我们希望建立一个公平的测试,因此创建了一项非常简单的微服务,其中不含外部依赖项(例如数据库),而且代码路径非常短(仅处理字符串)。我们在其中包含有指标及日志记录,因为似乎一切微服务都或多或少包含这些内容。另外,我们使用了小型、轻量化的框架(Helidon for Java 以及 Go-Kit for Go),两袖清风尝试了 Java 的纯 JAX-RS。我们也尝试了不同版本的 Java 与不同 JVM。我们对堆大小及垃圾收集机制做出基本调整,并在测试运行前对微服务进行了预热。

2. Java 的发展历史

Java 由 Sun Microsystems 公司开发,后被甲骨文所收购。其 1.0 版本发布于 1996 年,目前的最新版本是 2020 年的 Java 15。Java 当前的主要设计目标,在于实现 Java 虚拟机及字节码的可移植性,外加带有垃圾回收的内存管理机制。时至今日,Java 作为一种开源语言仍是全球最受欢迎的语言选项之一(根据 StackOverflow 及 TIOBE 等来源)。

下面来聊聊“Java 问题”。人们对于它速度缓慢的印象其实更多是种固有观念,而不再适应当下的事实。如今的 Java 甚至拥有不少性能敏感区,包括存储对象数据堆、用于管理堆的垃圾收集器,外加准时化(JIT)编译器。

Java微服务的优点有哪些

多年以来,Java 曾先后使用多种不同的垃圾收集算法,包括串行、并行、并发标记 / 清除、G1 以及最新的 ZGC 垃圾收集器。现代垃圾收集器旨在尽可能减少垃圾收集造成的暂停时长。

甲骨文实验室开发出一款名为 GraalVM 的 Java 虚拟机,其使用 Java 编写而成,具有新的编译器外加一系列令人兴奋的新功能,包括可以将 Java 字节码转换为无需 Java 虚拟机即可运行的原生镜像等。

3. Go 的发展历史

Go 语言由谷歌的 Robert Griesemer、Rob Pike 以及 Ken Thomson 开发而成。他们几位也是 UNIX、B、C、Plan9 以及 UNIX 视窗系统等项目的主要贡献者。作为一种开源语言,Go 的 1.0 版本发布于 2012 年,2020 年最新版本为 1.15。Go 语言的本体、采用速度以及工具生态系统的发展都相当迅猛。

Go 语言受到 C、Python、JavaScript 以及 C++ 的影响,已经成为一种理想的高性能网络与多处理语言。

截至我们发布主题演讲时,StackOverflow 上共有 27872 个带有“Go”标签的问题,Java 则为 1702730 个。

Go 是一种静态类型的编译语言,其语法类似于 C,且拥有内存安全、垃圾回收、结构化类型以及 CSP 样式并发(通信顺序过程)等功能特性。Go 还使用名为 goroutine 的轻量级进程(并非操作系统线程),外加各进程间用于通信的通道(类型化,FIFO)。Go 语言不提供竞态条件保护。

Go 是众多 CNCF 项目的首选语言,例如 Kubernetes、Istio、Prometheus 以及 Grafana 等皆是由 Go 语言编写而成(或者大部分是)。

Go 语言在设计上强调快速构建与快速执行。到底是两个空格还是四个空格?Go 语言表示不用麻烦,无所谓。

与 Java 相比,我将个人体会到的 Go 语言优势整理如下:

但 Go 当然也不完美。与 Java 相比,我认为 Go 存在以下问题:

工具生态系统还不成熟,特别是依赖项管理方面虽有多种选择,但还都不完美。在非开源开发方面,Go 模块在依赖项管理上优势明显,但由于存在某些兼容性问题,其采用率仍不算特别高。

构建具有新的 / 更新依赖项的代码时非常缓慢(例如 Maven 著称的「下载互联网」问题)。

导入会将代码绑定至 repo,导致代码移动非常困难。

IDE 非常适合编程、文档查找与自动补全等功能,但却难以进行调试及概要分析等。指针!我以为二十一世纪之前就可以告别这东西了,但 Go 里面还有!好在至少已经没有指针算法了。

没有 Java 那样的 try/catch 异常(最终总是要用到 if err != nil),也没有列表、映射函数等函数风格的原语。

某些基本算法仍然缺失,所以用户往往只能自行编写。最近我就编写了一些代码,用 sloe 对两个字符串(列表)进行比较以及转换。在函数语言中,我们完全可以使用 map 等内置算法完成。

没有动态链接!如果要在静态链接代码当中使用 GPL 等许可,就会很不方便。用于调整执行、垃圾收集、概要分析或者优化算法的选项很少。Java 拥有数百种垃圾收集调整选项,相比之下,Go 只有一项。

4. 负载测试方法

我们使用 JMeter 进行负载测试。测试多次调用服务,并收集关于响应时间、吞吐量(每秒事务)以及内存使用情况的数据。在 Go 方面,我们主要收集常驻集大小,Java 方面则主要跟踪原生内存。

在多项测试中,我们都将 JMeter 与被测应用程序放置在同一台计算机上运行。经过对比,我们发现在其他机器上运行 JMeter 几乎不会对结果造成任何影响。后续在将应用程序部署到 Kubernetes 中时,我们会考虑将 JMeter 运行在集群之外的远程计算机之上。

在进行测试之前,我们使用 1000 项服务调用对应用程序进行了预热。

应用程序本体的源代码以及负载测试定义请参见 GitHub repo:https://github.com/markxnelson/go-java-go

5. 首轮测试

在第一轮测试中,我们在小型机器上运行测试,搭载了 2.5 GHz 双核英特尔酷睿 i7 的笔记本电脑,具有 16 GB 内存并运行 MacOS。我们运行了 100 个线程,每个线程 10000 个循环,再额外加个 10 秒的启动时间。Java 应用程序运行在 JDK 11 与 Helidon 2.0.1 之上。Go 应用程序则使用 Go 1.13.3 进行编译。

测试结果如下:

Java微服务的优点有哪些

Java微服务的优点有哪些

我们宣布,Go 成为首轮测试的获胜者!

以下为根据这些结果得出的观察结论:

  日志记录似乎是影响性能的主要问题,特别是 java.util.logging。因此,我们在启用与禁用日志记录两种条件下进行了测试。我们还注意到,Go 应用程序性能主要受到日志记录的影响。

  即使对于如此简单的小型应用程序,Java 版本的内存占用量也明显更大。

  预热对 JVM 产生了很大影响——我们知道 JVM 在运行过程中会进行优化,因此预热对 Java 应用程序特别重要。

  在此测试中,我们还比较了不同的执行模型——Go 应用程序被编译为原生可执行二进制文件,而 Java 应用程序被编译为字节码,而后虚拟机上运行。我们还决定引入 GraalVM 原生镜像,保证 Java 应用程序的执行环境更接近 Go 应用程序。

6. GraalVM 原生镜像

GraalVM 提供原生镜像功能,使您能够使用 Java 应用程序并在实质上将其编译为原生可执行代码。根据 GraalVM 项目网站的介绍:

该可执行文件包含应用程序类、依赖项中的类、运行时库类以及 JDK 中的静态链接原生代码。其并非运行在 Java 虚拟机之上,而是包含必要组件,例如来自不同运行时系统(也被称为「基层虚拟机」)的内存管理、线程调度等功能。基层虚拟机代表的是各运行时组件(例如反优化器、垃圾收集器、线程调度等)。

在添加 GraalVM 原生镜像(原生镜像由 GraalVM EE 20.1.1——JDK 11 构建而成)之后,首轮测试结果如下:

Java微服务的优点有哪些

Java微服务的优点有哪些

在这种情况下,与运行在 JVM 上的应用程序相比,我们发现使用 GraalVM 原生镜像并不会在吞吐量或者响应时间等层面带来任何实质性的改善,但内存占用量确实有所减少。

以下是测试期间的响应时间图表:

Java微服务的优点有哪些

首轮响应时间图

请注意,在所有三种 Java 变体当中,第一批请求的响应时间要长得多(蓝线相较于左轴的高度)而且在各项测试中,我们还看到一些峰值,其可能是由垃圾收集或优化所引起。

7. 第二轮测试

接下来,我们决定在更大的计算机上运行测试。在本轮中,我们使用台具有 36 个核心(每核心双线程)、256 GB 内存的计算机,并配合 Oracle Linux 7.8 操作系统。与第一轮一样,我们仍然使用 100 个线程、每线程 10000 个循环,10 秒启动时间以及相同版本的 Go、Java、Helidon 以及 GraalVM。

下面来看结果:

Java微服务的优点有哪些

Java微服务的优点有哪些

我们宣布,GraalVM 原生镜像成为第二轮测试的赢家!

下面来看本轮测试的响应时间图:

Java微服务的优点有哪些

启用日志记录,但未经预热的测试运行响应时间

Java微服务的优点有哪些

不使用日志记录也未经预热的测试运行响应时间

Java微服务的优点有哪些

经过预热,但未使用日志记录的测试运行响应时间

第二轮的观察结果:

8. 第三轮测试:Kubernetes

在第三轮中,我们决定在 Kubernetes 集群上运行应用程序,借此模拟更为自然的微服务运行时环境。

在本轮中,我们使用包含三个工作节点的 Kubernets 1.16.8 集群,每个工作节点中包含两个核心(各对应两个线程)、14 GB 内存以及 Oracle Linux 7.8。在某些测试中,我们在变体上运行一个 Pod;在其他一些测试中,我们则运行一百个 Pod。

应用程序访问通过 Traefik 入口控制器实现,其中 JMeter 运行在 Kubernetes 集群之外。在某些测试中,我们也会尝试使用 ClusterIP 并在集群内运行 JMeter。与之前的测试一样,我们使用 100 个线程、每线程 10000 个循环,外加 10 秒启动时间。

以下是各个变体的容器大小:

以下为本轮测试结果:

响应时间图表:

Java微服务的优点有哪些

Kubernetes 测试中的响应时间

在本轮中,可以看到 Go 有时更快,而 GraalVM 原生镜像也经常取得领先,但二者的差异很小(一般低于 5%)。

9. 测试结论

纵观几轮测试与结果,我们得出了以下结论:

10.未来展望

经过这轮有趣的测试,我们打算继续探索,特别是:

到此,相信大家对“Java微服务的优点有哪些”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

推荐阅读:
  1. java Struts的优点有哪些
  2. Java有什么优点

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java

上一篇:数据库索引采用B树和B+树的原因是什么

下一篇:如何使用Java流程控制语句

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》