作者 | 程序猿DD   责编 | 张文

头图 | CSDN 下载自视觉中国

Java 微服务能像 Go 微服务一样快吗?这是我最近一直在思索的一个问题。

去年 8 月份的 the Oracle Groundbreakers Tour 2020 LATAM 大会上,Mark Nelson 和 Peter Nagy 就做过一系列基础的的测试用以比较两者。接下来就给大家介绍下。

在程序员圈子里,普遍的看法是 Java 老、慢、无聊 ,而 Go 是快、新、酷。

为了尽可能的进行一个相对公平的测试,他们使用了一个非常简单的微服务,没有外部依赖关系(比如数据库),代码路径非常短(只是操纵字符串),使用了小型的、轻量级的框架(Helidon for Java 和 Go 工具包 for Go),试验了不同版本的 Java 和不同的 jvm。

对决双雄

我们先来看下擂台两边的选手:

  • 身穿深色战服的选手是 JAVA

Java 是由被甲骨文收购的 Sun Microsystems 开发的。它的 1.0 版本是 1996 年发布的,最新的版本是 2020 年的 Java15。主要的设计目标是 Java 虚拟机和字节码的可移植性,以及带有垃圾收集的内存管理。它是全世界最流行的语言之一,在开源环境下开发。

我们先看下 JAVA 的问题,大家普遍认为它最大的问题就是速度慢,已经慢到让人觉得不再是合理的,而是更具历史意义的。不过这么多年来,Java 诞生了很多不同的垃圾收集算法用来加快它运行的速度。

Oracle 实验室最近已经开发了一个新的 Java 虚拟机 GraalVM,它有一个新的编译器和一些令人兴奋的新特性,比如能够将 Java 字节码转换成一个本机映像,可以在没有 javavm 的情况下运行等。

  • 而它的对手就是年轻充满活力的 GO

GO 是由谷歌的罗伯特·格里默、罗伯·派克和肯·汤姆森创建的。他们对 UNIX、B、C、Plan9、UNIX 窗口系统等做出了重大贡献。GO 是开源的,在 2012 年发布了 1.0 版本(比 JAVA 晚了 16 年),在 2020 年发布了 1.15 版本。无论是在采用方面,还是在语言和工具生态系统本身方面,它都在快速增长。

GO 受 C、Python、JavaScript 和 C++等多种语言的影响。被设计成高性能网络和多处理的最佳语言。

StackOverflow 有 27872 个带“Go”的问题,而 Java 只有 1702730个。足见长江后浪推前浪。

Go 是一种静态类型的编译语言。它有称为 goroutines 的轻量级进程(这些不是 OS 线程),它们之间有独特的通信通道(类型化的,FIFO)。Go 是许多 CNCF 项目的首选语言,例如 Kubernetes、Istio、Prometheus 和 Grafana

赛前对比

从个人感觉来说,Go 相比 JAVA 来说,优点在于:

  • Go 更容易实现复合、纯函数、不变状态等功能模式。

  • Go 处于生命周期的早期,因此它没有向后兼容性的沉重负担—Go 仍然可以轻易打破某些限制来改进。

  • Go 编译成一个本机静态链接的二进制文件-没有虚拟机层-二进制文件拥有运行程序所需的一切,这对于“从头开始”的容器来说非常好。

  • Go 体积小、启动快、执行快(目前是的)

  • Go 没有 OOP,继承,泛型,断言,指针算法

  • Go 写法上较少的括号

  • Go 没有循环依赖、没有未使用的变量或导入、没有隐式类型转换的强制

  • Go 样板代码少得多

缺点是:

  • Go 工具生态系统还不成熟,尤其是依赖关系管理——有几个选项,没有一个是完美的,特别是对于非开源开发;仍然存在兼容性挑战。

  • 构建具有新的/更新的依赖项的代码非常慢(比如 Maven 著名的“下载Internet”问题)

  • 导入将代码绑定到存储库,这使得在存储库中移动代码成为一场噩梦。

  • 调试、评测等仍然是一个挑战

  • 用到了指针

  • 需要实现一些基本的算法

  • 没有动态链接

  • 没有太多旋钮来调优执行或垃圾收集、概要文件执行或优化算法。

比赛开始

使用 JMeter 来运行负载测试。这些测试多次调用这些服务,并收集有关响应时间、吞吐量(每秒事务数)和内存使用情况的数据。对于 Go,收集驻留集大小;对于 Java,跟踪本机内存。

在测量之前,使用 1000 次服务调用对应用程序进行预热。

应用程序本身的源代码以及负载测试的定义都在这个 GitHub 存储库中:https://github.com/markxnelson/go-java-go

第一回合

在第一轮测试中,在一台“小型”机器上进行了测试,是一台 2.5GHz 双核 Intel core i7 笔记本电脑,16GB 内存运行 macOS。测试运行了 100 个线程,每个线程有 10000 个循环,上升时间为 10 秒。Java 应用程序运行在 JDK11 和 Helidon2.0.1上。使用 Go 1.13.3 编译的 Go 应用程序。

结果如下:

可以看出,第一回合是 Go 赢了!

JAVA 占的内存太多了;预热对 JVM 有很大的影响—我们知道 JVM 在运行时会进行优化,所以这是有意义的

在第一回合的基础上,意犹未尽的又引入 GraalVM 映像以使 Java 应用程序的执行环境更接近于 Go 应用程序的环境,添加了 GraalVM 映像测试(用  GraalVM EE 20.1.1ー JDK 11 构建的本机映像)的结果是:

通过使用 GraalVM 映像在 JVM 上运行应用程序,我们没有看到吞吐量或响应时间方面的任何实质性改进,但是内存占用的确变小了。

下面是一些测试的响应时间图:

第二回合

在第二轮测试中,使用一台更大的机器上运行测试。36 核(每个核两个线程)、256GB 内存、运行 oraclelinux7.8 的机器。

和第一轮类似,使用了 100 个线程,每个线程使用了 10,000 个循环,10 秒的加速时间,以及相同版本的 Go,Java,Helidon 和 GraalVM。

结果如下:

这一回合是 GraalVM 映像赢了!

下面是一些测试的响应时间图:

在这个测试中,Java 变体的表现要好得多,并且在没有使用 Java 日志记录的情况下,它的性能大大超过了 Go。Java 似乎更能使用硬件提供的多核和执行线程(与 Go 相比)。

这一轮的最佳表现来自 GraalVM native image,平均响应时间为 0.25 毫秒,每秒事务数为 82426 个,而 Go 的最佳结果为 1.59 毫秒和 39227 个 tps,然而这是以多占用两个数量级的内存为代价的!

GraalVM 映像比在 jvm 上运行的同一应用程序快大约 30–40%!

第三回合

这次,比赛在 Kubernetes 集群中运行这些应用程序,这是一个更自然的微服务运行时环境。

这次使用了一个 Kubernetes 1.16.8 集群,它有三个工作节点,每个节点有两个内核(每个内核有两个执行线程)、14GB 的 RAM 和 oraclelinux7.8。

应用程序访问是通过 Traefik 入口控制器进行的,JMeter 在 Kubernetes 集群外运行,用于一些测试,而对于其他测试,使用 ClusterIP 并在集群中运行 JMeter。

与前面的测试一样,使用了 100 个线程,每个线程使用了 10,000 个循环,以及 10 秒的加速时间。

下面是各种不同容器的大小:

  • Go 11.6MB 11.6 MB

  • Java/Helidon 1.41GB 1.41 GB

  • Java/Helidon JLinked 150MB 150mb

  • Native image 25.2MB 25.2 MB

结果如下:

下面是一些测试的响应时间图:

在这一轮中,我们观察到 Go 有时更快,GraalVM 映像有时更快,但这两者之间的差别很小(通常小于 5%)。

Java 似乎比 Go 更善于使用所有可用的内核/线程—在 Java 测试中看到了更好的 CPU 利用率。Java 性能在拥有更多内核和内存的机器上更好,Go 性能在较小/功能较弱的机器上更好。在一台“生产规模”的机器上,Java 很容易就和 Go 一样快,或者更快。

最后

接下来会做更多的测试比赛,来看一看究竟谁更好!

有兴趣的你也可以自己试一试,记得告诉我们结果哦!

参考链接:https://medium.com/helidon/can-java-microservices-be-as-fast-as-go-5ceb9a45d673

程序员如何避免陷入“内卷”、选择什么技术最有前景,中国开发者现状与技术趋势究竟是什么样?快来参与「2020 中国开发者大调查」,更有丰富奖品送不停!

更多精彩推荐
☞突发!小米被美国政府“拉黑”;联发科每名员工获 10 万大红包;腾讯 7 款 APP 遭责令整改 | 极客头条☞放弃 PHP,选择 Node.JS 的 8 个理由!
☞程序员求生指南:告别大小周,摆脱监视,直奔年终奖!☞1.6 万亿参数你怕了吗?谷歌大脑语言模型速度是 T5 速度的 7 倍☞2020 ACM Fellows 名单出炉,13 名华人入选,7 名来自国内!
☞再次被替代?六成应用开发不需要程序员点分享点收藏点点赞点在看

戳”阅读原文“,

有奖参与中国开发者大调查!

Java VS Go,微服务究竟谁更快?相关推荐

  1. Spring Cloud 与微服务学习总结(14)—— 云原生时代,如何从 Java 开发者转型微服务?

    前言 根据维基百科定义,微服务不是整体应用程序中的一个层.相反,微服务是一个独立的业务功能,具有清晰的接口,并且可以通过内部组件实现分层架构.从战略角度来看,微服务架构基本上遵循"做一件事, ...

  2. 秒杀springboot——未来轻量级高性能的Java云原生微服务框架来啦

    秒杀springboot--未来轻量级高性能的Java云原生微服务框架来啦 引子 自2003年Rod.Juergen 和 Yann开发并发布Spring项目后,J2EE 迎来了新的开始.在 2013 ...

  3. JAVA | 什么是微服务?

    前言 最近公司某个项目的架构越来越庞大,维护起来非常难受.领导提出要把这个项目重构,在工作中需要把原来的项目重构成微服务架构,因此学习微服务相关知识,在这里记录下来,权当笔记的同时也希望能对你有启发. ...

  4. java计算机毕业设计微服务”架构下新闻头条的设计与实现源码+系统+数据库+lw文档

    java计算机毕业设计微服务"架构下新闻头条的设计与实现源码+系统+数据库+lw文档 java计算机毕业设计微服务"架构下新闻头条的设计与实现源码+系统+数据库+lw文档 本源码技 ...

  5. 13 年 Java 老兵的微服务战地笔记 | 文末有1元福利

    * 文末有仅限 24 小时的 1 元福利,错过别怪我!!! 微服务在业内的实践已经从流行走向成熟,诸多公司(比如 Amazon.Netflix.蚂蚁金服.网易云音乐等)都已经迁移并采用了微服务架构.而 ...

  6. python io密集 多线程_python多进程和多线程究竟谁更快(详解)

    python3.6 threading和multiprocessing 四核+三星250G-850-SSD 自从用多进程和多线程进行编程,一致没搞懂到底谁更快.网上很多都说python多进程更快,因为 ...

  7. Java面试题-微服务

    微服务 1. 前后端分离具体如何实现 现主流前后端分离多数为: 前端:Vue/Angular/React 中间件:Nodejs 后端:Java/Go 前后端交互基于Nodejs作为中间层,不再直接进行 ...

  8. Java 云原生微服务框架 Quarkus 入门实践

    点击上方"芋道源码",选择"设为星标" 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | ...

  9. java实现的微服务架构_详解Java 微服务架构

    一.传统的整体式架构 传统的整体式架构都是模块化的设计逻辑,如展示(Views).应用程序逻辑(Controller).业务逻辑(Service)和数据访问对象(Dao),程序在编写完成后被打包部署为 ...

最新文章

  1. udhcp server端源码分析1--文件组织结构
  2. AM3354开发 -- 使用root模式登录Ubuntu18.04
  3. Exception in thread main java.lang.RuntimeException: java.lang.IllegalArgumentException: java.net.
  4. leetcode733. 图像渲染(bfs)
  5. 微信怎么at所有人_微信分付怎么开通,入口在这里,简单几步教你快速开通
  6. 浅谈最短路径的几个方法(Dijkstra,Bellman-Ford,SPFA,Floyd算法)
  7. POJ - 2891 中国剩余定理
  8. 最全java面试题及答案(208道)
  9. Loadrunner11破解完成添加License失败
  10. Eclipse搭建Android开发环境并运行Android项目 (详细)
  11. Wi-Fi连接握手包抓包
  12. 服务器上传图片不显示,网站后台上传图片失败或不显示的原因
  13. 正则匹配0-999区间数字
  14. one 主格 复数 宾格_代词专练(名词性物主代词,形容词性物主代词,宾格,主格,复数)...
  15. Java中ArrayList的练习
  16. C# 透明背景Panel, 透明图像, PitureBox透明效果
  17. loadrunner如何确定预期TPS
  18. viewpager切页
  19. smartupload工具上传文件
  20. ipad和iphone切图_如何在iPhone,iPad和Apple TV上设置Steam Link

热门文章

  1. Activity之间的数据传递—实现Parcelable接口
  2. VScode设置console.log('')快捷键
  3. 面试—每日一题(7)
  4. 面试—每日一题(3)
  5. 5.Ray-Handler之ToReadHandler编写
  6. 分享一种固定页教在页面底部的方法
  7. 常用STL整理 (施工中 2017.8.11更新)
  8. Python编程练习题
  9. Java关键字final、static
  10. Asp.net安全相关注意的几个问题