云原生时代是Java还是Go

技术云原生时代是Java还是Go这篇文章主要讲解了“云原生时代是Java还是Go”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“云原生时代是Java还是Go”吧!Java曾

本文主要讲解“最初的云时代是Java还是Go”。本文的讲解内容简单明了,易学易懂。请跟随边肖的思路,一起学习和学习“原云时代是Java还是Go”。

Java曾经著名的座右铭:‘写一次,到处跑’已经过时了,因为现在我们只想运行容器中的代码。在容器中,“及时”编译器没有什么意义。

正因如此,或许是为了更好地适应云计算,Java生态系统正在经历转型。Oracle的GraalVm允许将字节码编译成Linux可执行文件(ELF),而Rad Heat的Quarkus和其他框架则决心让响应服务变得更容易。以Netty和Vertx.x为核心,Quarkus可以用来构建高效响应的Web服务。

云原生时代是Java还是Go

Java被编译成可执行的二进制文件,以毫秒级的速度启动,占用少量内存。通过这种方式,您可以利用Java生态系统,甚至可以用其他JVM语言编写,如Scala和Kotlin。您可以使用在线项目生成器玩Quarkus,或者使用maven插件在本地生成项目。

另一方面,Golang是为云而生的,当它在容器中运行时,没有遗留负担。它被认为是云的编程语言。生成的二进制可执行文件很小,可以快速启动,占用内存很少。而且,这个特性从Go诞生开始就具备了。Golang的流行给Java世界带来了严峻的挑战。

Java有机会吗?也许只有时间会告诉我们最终的答案。但是,出于好奇,我想从性能和开发体验方面比较一下Java和Golang的云原生服务。

在本文中,我将用两种语言编写相同的服务。比较它们的CPU使用率、内存、延迟和运行速度。这些服务将以相同的资源分配在容器中启动,并将由ab进行测试。

对我来说,这是一个“足够好”的基准测试,因为我不会假设找到最佳/最差的基准测试结果,而是在同一环境中运行两个基准测试进行比较。

场景

这两个服务将连接到另一个容器中运行的MySQL数据库,该数据库有一个表和三行数据。

云原生时代是Java还是Go

每个服务获取所有记录,将它们转换成对象,然后输出JSON数组。

ab将发出并发级别为100的10K请求,quarkus JVM版本将运行两次(用于测试“冷”/“暖”JVM)。

云原生时代是Java还是Go

Go语言版本

Go语言版本使用gin框架。

# servicepackagemainimport(' database/SQL ' ' fmt ' ' github.com/gin-gonic/gin ' _ ' github.com/go-SQL-driver/MySQL ' ' net/http ')typeFundstruct { Idint ` js : ' id ' ` Namestring ` js : ' name ' ` } varcon * SQL。DBfuncinit(){//open ingmysql connectionpoolwithnercontainerdb,err:=sql。Open('mysql ',' root:

password@tcp(host.docker.internal:3306)/payments")    if err != nil {        panic("failed to open a mysql connection")    }    con = db }  func main() {     r := gin.Default()     r.GET("/fruits", fruits)     r.Run() //server up on 8080 }  // THE REQUEST HANDLER func fruits(c *gin.Context) {     fruits := getFruits()     c.JSON(http.StatusOK, fruits) }  func getFruits() []Fruit {     rows, _ := con.Query("SELECT * FROM fruits")     fruits := []Fruit{}     for rows.Next() {         var r Fruit         rows.Scan(&r.Id, &r.Name)         fruits = append(fruits, r)     }     return fruits }

Golang的MySQL驱动的使用go-sql-driver。golang的代码风格是非常明确的。一种一切都在眼前态度。主函数启动服务器,配置请求处理程序,打开DB连接。

编译本地可执行文件

云原生时代是Java还是Go

Kotlin版本

package org.acme import io.vertx.core.json.JsonArray import io.vertx.core.json.JsonObject import io.vertx.mutiny.mysqlclient.MySQLPool import io.vertx.mutiny.sqlclient.Row import io.vertx.mutiny.sqlclient.RowSet import java.util.concurrent.CompletionStage import javax.inject.Inject import javax.ws.rs.GET import javax.ws.rs.Path import javax.ws.rs.Produces import javax.ws.rs.core.MediaType  @Path("/fruits") class FruitResource {     @field:Inject     lateinit var client: MySQLPool       @GET     @Produces(MediaType.APPLICATION_JSON)     fun listFruits(): CompletionStage<JsonArray> {         return client.query("SELECT * FROM fruits").execute()                 .map { rows: RowSet<Row> ->                     rows.fold(JsonArray()) { array, row ->                         array.add(JsonObject()                                 .put("id", row.getLong("id"))                                 .put("name", row.getString("name")))                     }                 }.subscribeAsCompletionStage()     } }

数据库连接使用Quarkus React Mysql 扩展。

云原生时代是Java还是Go

与Go版本相比,代码有很大不同,比如CDI依赖注入,使用javax注释的声明式路由,自动配置解析,以及数据源/连接创建/服务器引导。这是使用框架的代价,它为你完成了繁重的工作,并决定了做事方式。不过,它比go版本代码要简短很多。

这里使用Netty响应式web服务器,由Vert.x多事件循环包装,还有一个Vert.x响应式MySQL驱动,这样可以用一个线程处理多个DB连接。

另外,我可以使用Kotlin的集合库的fold函数,这种函数还没有通用的Go版本。

编译Java版本的可执行文件

云原生时代是Java还是Go

我已经弄清楚构建过程中发生了什么,其核心是SubstrateVM。它被设计在AOT过程中的可嵌入虚拟机,它会链接到我们的代码,并作为一个单元进行编译。然而根据Oracle的说法,SubstrateVM的优化比HotSpot  Vm少,垃圾收集器也比较简单。

该AOT编译器被称为  "Graal",它是语言不相关的。java字节码需要被翻译成一种中间表示法(Truffle语言)。这在这篇文章【1】中可以找到关于Graal和Truffle的相关论述。

构建一个 Java 本地可执行文件看起来更复杂,编译得更慢,它产生的二进制文件几乎是Go版本两倍大小。然而一个35M的可执行二进制文件和Java  FatJar相比,还是小D多了。35MB甚至可以让你使用aws lambda运行。

压力测试

我在本机运行所有测试,设置如下。

  • MacBook Pro(15英寸,2017年

  • 2.9 GHz英特尔酷睿i7(8个核心)。

  • 16 GB 2133 MHz LPDDR3

使用cAdvisor的工具来监控容器的统计数据。

场景

  • Quarkus JVM hotspot

  • Quarkus Java native

  • Golang

上述的每种情况都在以下三种配置上测试

  • 100MB / 0.5 CPU | 200MB / 1 CPU | 300MB / 2 CPU

我主要关注:

  • cpu/ram利用率(多核的利用率)

  • cpu/ram峰值

  • cpu/ram空余

  • 启动时间

  • 响应延迟avg/max

  • 吞吐量(每秒请求数)

测试结果

云原生时代是Java还是Go

看起来Quarkus已经为生产环境做好准备了,它允许简单的JVM/原生发布/开发  模式,并允许在本地运行原生测试。只要你不使用反射或JNI,根据GraalVM的配置就是可行的。否则,你将不得不自己配置graal编译器,然而现在也有解决方案。

延迟和吞吐量

Golang 和原生 Java 的测试结果比较接近,虽然平均来说 Golang 版本的测试结果略好一些。不过,Java  Native版本的测试结果更稳定。Golang服务有时在1.25&mu;s内完成响应,也有一部分需要7s才能完成。

"预热 "后的JVM版本结果也不差,但比Native或Go版本稍逊一筹。

CPU利用率

使用0.5核的时候,Go和native-java在负载下似乎都表现不佳,而用2核启动时,也没有明显改善。这可能是因为工作负载的瓶颈是IO。或者是因为gin/Netty的默认配置没有考虑到多核的问题。

而JVM版本则利用了所有给定的核心,并在各个维度上提升了性能。

内存使用率

在压力下,Java native 使用40MB,Golang 使用24MB。两种情况下都还不错,虽然Golang版本使用的内存几乎少了一倍。

JVM使用了140MB。和Quarkus官方的统计完全一样。对于JVM来说还不错,但比Golang版本多了近6倍。

启动时间

Golang和cloud-native  java都能立即启动,然而JVM版本需要几秒钟(取决于分配的CPU),并且在启动时产生CPU峰值。如果配置不当,会导致k8s  HPA发飙,并增加pods。

开发体验

这与其说是一个实际问题,不如说是一个宗教问题。Quarkus 使用了在 Java  世界中很常见的抽象(比如基于注解的DI)。它为你启动服务并创建连接池。它可以使用丰富的集合标准库和generics。然而,这可能感觉有点像黑魔法,一旦有些组件不工作,你会感觉很无助。此外,将  Java  代码编译成原生二进制并不是那么简单,有一些限制和注意事项是你必须知道的,并非每个Java库都能兼容原生编译。一旦使用一个不兼容的库(比如Guice),你就需要自己配置Graal  VM。

Quarkus 和 Graal VM "相对  "较新。所以可能会有一些问题。但由于双模式(JVM或原生)。在原生版本的某些组件停止工作的情况下,总是有一个后备方案,这对任何新问题来说都是很好的变通方法。

另一方面,Golang 在成立10年后才承认它需要generics。而且它肯定不喜欢框架使用很多魔法操作。这在很多方面既是好事也是坏事。此外,尽管 Go  社区做的非常好,然而可用的工具和库还是相对较少。然而它的编译和构建过程更快/更简单。而且兼容每个Golang的包,没有java-native平台带来的限制。

感谢各位的阅读,以上就是“云原生时代是Java还是Go”的内容了,经过本文的学习后,相信大家对云原生时代是Java还是Go这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/57106.html

(0)

相关推荐

  • 令字加偏旁,“令”加什么偏旁变成新字

    技术令字加偏旁,“令”加什么偏旁变成新字令字可以加令字加偏旁: 冫偏旁,组词新字是:冷。令字可以加: 山偏旁,组词新字是:岭。令字可以加: 王偏旁,组词新字是:玲。令字可以加:亻偏旁,组词新字是:伶。冷拼音:lěng

    生活 2021年10月28日
  • ORACLE中出现ORA-28365错误怎么办

    技术ORACLE中出现ORA-28365错误怎么办这篇文章主要为大家展示了“ORACLE中出现ORA-28365错误怎么办”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“ORA

    攻略 2021年11月20日
  • Struts2 checkbox适用场景及分析是这样的

    技术Struts2 checkbox适用场景及分析是这样的Struts2 checkbox适用场景及分析是这样的,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,

    攻略 2021年11月16日
  • 图像处理—图像的旋转

    技术图像处理—图像的旋转 图像处理—图像的旋转此处不叙述公式的推导,只是以初学者的角度理顺思路与总结重要知识点。
    图像的旋转公式为
    $$\left\{\begin{array}{c}i^{'}=icos

    礼包 2021年12月24日
  • 体育模拟

    技术体育模拟 体育模拟import randomdef printInfo(): print("模拟体育竞技") print("学号后两位:26,曾俊谌")
    def getInputs():

    礼包 2021年11月14日
  • 如何实现mvvmlight与icommand类

    技术如何实现mvvmlight与icommand类小编给大家分享一下如何实现mvvmlight与icommand类,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们

    攻略 2021年11月23日