Java VS Go,微服务究竟谁更快?

2021-01-18 14:15发布

15条回答
小小收藏家
2楼 · 2021-01-18 16:19

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

kitidog2016
3楼 · 2021-01-18 16:52

ava微服务能像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存储库中;

第一回合

在第一轮测试中,在一台“小型”机器上进行了测试,是一台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一样快,或者更快


香蕉牛油果酸奶
4楼 · 2021-01-18 18:25

按主流的实现单进程应该是go > java > pypy,因为pypy有GIL,不能充分利用多核性能。但其实这个问题没有太大意义,因为这个跟HTTP server的实现密切相关,完整的框架有更多功能,空跑的性能也会低一些。Go的handler很高效,也很轻,额外的功能很少,所以很快;但如果你实现一个完全不解析HTTP协议、连接进来就直接发送HTTP 200 OK的“HTTP服务器”,那可能会更快,但拿来比显然不合适。Java的主流Web实现本身就是比较完整的东西了,有前端,协议解析,线程池,任务管理之类的,大约相当于Python的WSGI,如果是Servelet比WSGI的话,那应该还是Java要快不少。

Sunny
5楼 · 2021-01-18 19:04

说实话,看你学习编程的目的是什么?

如果你就像追求新技术,哪建议你研究学习Go

如果你是为了学习尽快找到一份合适的工作,建议你还是先学习JAVA


Go语言性能和效率肯定不错,但是没有完整的生态体系,很多企业级应用开发,都要自己从零一点点做起

开发难度很大!

而JAVA非常成熟稳定,适合企业级开发!

像风没有归宿
6楼 · 2021-01-19 09:22

java有完善的知识体系,go目前的知识体系相比没有java完善,所以实际深入学习的情况下从go入门深入的难度会比java高。对于后期发展主要在于你对知识体系的掌握,目前go更偏向中间件和微服务,java则覆盖范围比较广,至于说后期发展和薪资的关系,还要看你的运气和实力。



py大白
7楼 · 2021-01-19 09:45

ava微服务能像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”问题)

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

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

用到了指针

需要实现一些基本的算法

没有动态链接

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


可口可乐
8楼 · 2021-01-19 09:56

说实话,看你学习编程的目的是什么?

如果你就像追求新技术,哪建议你研究学习Go

如果你是为了学习尽快找到一份合适的工作,建议你还是先学习JAVA


Go语言性能和效率肯定不错,但是没有完整的生态体系,很多企业级应用开发,都要自己从零一点点做起

开发难度很大!

而JAVA非常成熟稳定,适合企业级开发!


希希
9楼 · 2021-01-19 14:27

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

相关问题推荐

  • 回答 36

    看军事新闻的同学应该都知道,一艘航空母舰作战能力虽然很强,但是弱点太明显,就是防御能力太差,单艘的航空母舰很少单独行动,通常航空母舰战斗群才是主要军事力量,你可以把单艘航母理解为的单体应用(防御差,机动性不好),把航母战斗群(调度复杂,维护...

  • 回答 31

    初始化过程细节:首先进行的就是将服务装载到容器中,然后准备注册服务。和Spring中启动过程类似,Spring启动时,将bean装载进容器中的时候,首先要解析bean。所以dubbo也是先读配置文件解析服务。解析服务:基于dubbo.jar内的META-INF/spring.handlers配置,...

  • 回答 27

    分布式事务 指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上 。换成比较容易理解的话,就是多个事务之间再保持事务的特性,也就是多个事务之间保证结果的一致性。分布式事务解决方案1、基于XA协议的两阶...

  • 什么是接口幂等性?2021-02-24 18:21
    回答 25

    1. 接口调用存在的问题        现如今我们的系统大多拆分为分布式SOA,或者微服务,一套系统中包含了多个子系统服务,而一个子系统服务往往会去调用另一个服务,而服务调用服务无非就是使用RPC通信或者restful,既然是通信,那么就有可能在服务器处理...

  • 回答 21

    前提是另外一个bean在bean容器中能找到

  • 回答 22

    1.View——表示层1.1准备数据实现方式:struts,servlet等1.2显示数据实现方式:extjs,jsp,jquery,html等2.Service——业务层实现方式:drools等3.Dao——数据访问层实现方式:hibernate、mybatis等...

  • SpringCloud Netflix和Sprin2020-11-12 09:41
    回答 8
    已采纳

    SpringCloud Netflix和SpringCloud Alibaba的区别如下图:

  • 回答 16

    哨兵(Sentinel)是 redis 的高可用性解决方案,前面我们讲的主从复制它是高可用的基础,需要人工介入才能完成故障转移,哨兵可以解决这个问题,在主从复制情况下,当主节点发生故障时,哨兵可以自动的发现故障并且完成故障转移,实现真正的 redis 高可用。在...

  • 回答 8

    redis为什么会有高并发问题redis的出身决定Redis是一种单线程机制的nosql数据库,基于key-value,数据可持久化落盘。由于单线程所以redis本身并没有锁的概念,多个客户端连接并不存在竞争关系,但是利用jedis等客户端对redis进行并发访问时会出现问题。发生连...

  • 回答 8

    用dubbo是想利用分布式集群的形式来提高服务的并发量,适用与大型项目.如果不用它还想提高并发另一个解决方案是springCloud+微服务.适合大中小型项目.当前对并发要求的项目还是很多的,所以dubbo用的也相对较多.建议如果是初学者可以跳过dubbo直接学习第二个方...

  • 回答 4

    不需要。一般是service分出去。然后其它放在web层即一个jar为service业务处理,一个为web层war包

  • 回答 7

    在回答这个问题之前,我们先回答一下什么是锁。普通的锁,即在单机多线程环境下,当多个线程需要访问同一个变量或代码片段时,被访问的变量或代码片段叫做临界区域,我们需要控制线程一个一个的顺序执行,否则会出现并发问题。如何控制呢?就是设置一个各个线...

  • 回答 6

     springmvc位于表现层,主要与浏览器进行交互(接收和响应浏览器请求)。springmvc采用MVC设计模型,模型由model、view和controller组成。         model(模型):对应JavaBean         view(视图):对应JSP         controller(控制器)...

没有解决我的问题,去提问