成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

云原生時(shí)代,Java還是Go?

開發(fā) 后端 云原生
Java曾經(jīng)著名的座右銘:"一次編寫,到處運(yùn)行",已經(jīng)很過時(shí)了,因?yàn)楝F(xiàn)在我們只想在容器里運(yùn)行代碼。在容器里,一個(gè) "Just in time "的編譯器意義不大。

Java曾經(jīng)著名的座右銘:"一次編寫,到處運(yùn)行",已經(jīng)很過時(shí)了,因?yàn)楝F(xiàn)在我們只想在容器里運(yùn)行代碼。在容器里,一個(gè) "Just in time "的編譯器意義不大。

出于這個(gè)原因,可能為了更好地適應(yīng)云計(jì)算,Java生態(tài)系統(tǒng)正處于轉(zhuǎn)型之中。Oracle 的GraalVm允許將字節(jié)碼編譯成Linux可執(zhí)行文件(ELF),而Rad Heat的Quarkus以及其他框架,則立志讓響應(yīng)式服務(wù)這件事變得更簡單。Quarkus以Netty和Vertx.x為核心,可以用來構(gòu)建非常高效的響應(yīng)式Web服務(wù)。

 

Java編譯成可執(zhí)行二進(jìn)制文件,以毫秒級的速度啟動,內(nèi)存占用很小。這樣就可以利用Java生態(tài)系統(tǒng),甚至可以用其他JVM語言(如Scala和Kotlin)編寫。你可以用online項(xiàng)目生成器玩玩Quarkus,或者用maven插件在本地生成一個(gè)項(xiàng)目。

而Golang則是為云而生的,在容器中運(yùn)行時(shí),沒有遺留負(fù)擔(dān)。它被認(rèn)為是云端的編程語言。生成的二進(jìn)制可執(zhí)行文件很小,快速啟動,內(nèi)存占用也很小,而且這是從Go誕生之初就具備的特性。Golang的流行對 Java 世界形成了嚴(yán)峻的挑戰(zhàn)。

Java有機(jī)會嗎,也許只有時(shí)間才會告訴我們最終答案。然而,出于好奇,我想從性能和開發(fā)體驗(yàn)方面比較一下 Java 和 Golang 的云原生服務(wù)。

在這篇文章中,我將使用兩種語言來寫同樣的服務(wù)。比較它們的CPU使用率、RAM、延遲和運(yùn)行速度。這些服務(wù)將在容器中啟動,資源分配相同,使用ab來測試。

對于我的案例來說,這是一個(gè) "足夠好 "的基準(zhǔn),因?yàn)槲也患僭O(shè)找到最好/最差的基準(zhǔn)結(jié)果,而是在同一環(huán)境下執(zhí)行運(yùn)行兩個(gè)基準(zhǔn)測試進(jìn)行比較。

場景

這兩個(gè)服務(wù)將連接到在另一個(gè)容器中運(yùn)行的MySQL數(shù)據(jù)庫,有一個(gè)表和三行數(shù)據(jù)。

 

每一個(gè)服務(wù)都會獲取所有記錄,將它們轉(zhuǎn)化為對象,然后輸出JSON數(shù)組。

ab將發(fā)出10K請求,并發(fā)級別為100,quarkus JVM版本運(yùn)行兩次(用于測試 "冷"/"暖 "JVM)。

 

Go語言版本

Go語言版本使用gin框架。

  1. # the service 
  2. package main 
  3.  
  4. import ( 
  5.     "database/sql" 
  6.     "fmt" 
  7.     "github.com/gin-gonic/gin" 
  8.     _ "github.com/go-sql-driver/mysql" 
  9.     "net/http" 
  10.  
  11. type Fruit struct { 
  12.     Id  int `json:"id"
  13.     Name string `json:"name"
  14.  
  15. var con *sql.DB 
  16.  
  17. func init(){ 
  18.   //opening a mysql connection pool with another container 
  19.    db, err := sql.Open("mysql""root:password@tcp(host.docker.internal:3306)/payments"
  20.    if err != nil { 
  21.        panic("failed to open a mysql connection"
  22.    } 
  23.    con = db 
  24.  
  25. func main() { 
  26.     r := gin.Default() 
  27.     r.GET("/fruits", fruits) 
  28.     r.Run() //server up on 8080 
  29.  
  30. // THE REQUEST HANDLER 
  31. func fruits(c *gin.Context) { 
  32.     fruits := getFruits() 
  33.     c.JSON(http.StatusOK, fruits) 
  34.  
  35. func getFruits() []Fruit { 
  36.     rows, _ := con.Query("SELECT * FROM fruits"
  37.     fruits := []Fruit{} 
  38.     for rows.Next() { 
  39.         var r Fruit 
  40.         rows.Scan(&r.Id, &r.Name
  41.         fruits = append(fruits, r) 
  42.     } 
  43.     return fruits 

Golang的MySQL驅(qū)動的使用go-sql-driver。golang的代碼風(fēng)格是非常明確的。一種一切都在眼前態(tài)度。主函數(shù)啟動服務(wù)器,配置請求處理程序,打開DB連接。

編譯本地可執(zhí)行文件

 

Kotlin版本

  1. package org.acme 
  2. import io.vertx.core.json.JsonArray 
  3. import io.vertx.core.json.JsonObject 
  4. import io.vertx.mutiny.mysqlclient.MySQLPool 
  5. import io.vertx.mutiny.sqlclient.Row 
  6. import io.vertx.mutiny.sqlclient.RowSet 
  7. import java.util.concurrent.CompletionStage 
  8. import javax.inject.Inject 
  9. import javax.ws.rs.GET 
  10. import javax.ws.rs.Path 
  11. import javax.ws.rs.Produces 
  12. import javax.ws.rs.core.MediaType 
  13.  
  14. @Path("/fruits"
  15. class FruitResource { 
  16.     @field:Inject 
  17.     lateinit var client: MySQLPool 
  18.  
  19.  
  20.     @GET 
  21.     @Produces(MediaType.APPLICATION_JSON) 
  22.     fun listFruits(): CompletionStage<JsonArray> { 
  23.         return client.query("SELECT * FROM fruits").execute() 
  24.                 .map { rows: RowSet<Row> -> 
  25.                     rows.fold(JsonArray()) { array, row -> 
  26.                         array.add(JsonObject() 
  27.                                 .put("id", row.getLong("id")) 
  28.                                 .put("name", row.getString("name"))) 
  29.                     } 
  30.                 }.subscribeAsCompletionStage() 
  31.     } 

數(shù)據(jù)庫連接使用Quarkus React Mysql 擴(kuò)展。

 

與Go版本相比,代碼有很大不同,比如CDI依賴注入,使用javax注釋的聲明式路由,自動配置解析,以及數(shù)據(jù)源/連接創(chuàng)建/服務(wù)器引導(dǎo)。這是使用框架的代價(jià),它為你完成了繁重的工作,并決定了做事方式。不過,它比go版本代碼要簡短很多。

這里使用Netty響應(yīng)式web服務(wù)器,由Vert.x多事件循環(huán)包裝,還有一個(gè)Vert.x響應(yīng)式MySQL驅(qū)動,這樣可以用一個(gè)線程處理多個(gè)DB連接。

另外,我可以使用Kotlin的集合庫的fold函數(shù),這種函數(shù)還沒有通用的Go版本。

編譯Java版本的可執(zhí)行文件

 

我已經(jīng)弄清楚構(gòu)建過程中發(fā)生了什么,其核心是SubstrateVM。它被設(shè)計(jì)在AOT過程中的可嵌入虛擬機(jī),它會鏈接到我們的代碼,并作為一個(gè)單元進(jìn)行編譯。然而根據(jù)Oracle的說法,SubstrateVM的優(yōu)化比HotSpot Vm少,垃圾收集器也比較簡單。

該AOT編譯器被稱為 "Graal",它是語言不相關(guān)的。java字節(jié)碼需要被翻譯成一種中間表示法(Truffle語言)。這在這篇文章【1】中可以找到關(guān)于Graal和Truffle的相關(guān)論述。

構(gòu)建一個(gè) Java 本地可執(zhí)行文件看起來更復(fù)雜,編譯得更慢,它產(chǎn)生的二進(jìn)制文件幾乎是Go版本兩倍大小。然而一個(gè)35M的可執(zhí)行二進(jìn)制文件和Java FatJar相比,還是小D多了。35MB甚至可以讓你使用aws lambda運(yùn)行。

壓力測試

我在本機(jī)運(yùn)行所有測試,設(shè)置如下。

  • MacBook Pro(15英寸,2017年
  • 2.9 GHz英特爾酷睿i7(8個(gè)核心)。
  • 16 GB 2133 MHz LPDDR3

使用cAdvisor的工具來監(jiān)控容器的統(tǒng)計(jì)數(shù)據(jù)。

場景

  • Quarkus JVM hotspot
  • Quarkus Java native
  • Golang

上述的每種情況都在以下三種配置上測試

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

我主要關(guān)注:

  • cpu/ram利用率(多核的利用率)
  • cpu/ram峰值
  • cpu/ram空余
  • 啟動時(shí)間
  • 響應(yīng)延遲avg/max
  • 吞吐量(每秒請求數(shù))

測試結(jié)果

 

看起來Quarkus已經(jīng)為生產(chǎn)環(huán)境做好準(zhǔn)備了,它允許簡單的JVM/原生發(fā)布/開發(fā) 模式,并允許在本地運(yùn)行原生測試。只要你不使用反射或JNI,根據(jù)GraalVM的配置就是可行的。否則,你將不得不自己配置graal編譯器,然而現(xiàn)在也有解決方案。

延遲和吞吐量

Golang 和原生 Java 的測試結(jié)果比較接近,雖然平均來說 Golang 版本的測試結(jié)果略好一些。不過,Java Native版本的測試結(jié)果更穩(wěn)定。Golang服務(wù)有時(shí)在1.25μs內(nèi)完成響應(yīng),也有一部分需要7s才能完成。

"預(yù)熱 "后的JVM版本結(jié)果也不差,但比Native或Go版本稍遜一籌。

CPU利用率

使用0.5核的時(shí)候,Go和native-java在負(fù)載下似乎都表現(xiàn)不佳,而用2核啟動時(shí),也沒有明顯改善。這可能是因?yàn)楣ぷ髫?fù)載的瓶頸是IO?;蛘呤且?yàn)間in/Netty的默認(rèn)配置沒有考慮到多核的問題。

而JVM版本則利用了所有給定的核心,并在各個(gè)維度上提升了性能。

內(nèi)存使用率

在壓力下,Java native 使用40MB,Golang 使用24MB。兩種情況下都還不錯(cuò),雖然Golang版本使用的內(nèi)存幾乎少了一倍。

JVM使用了140MB。和Quarkus官方的統(tǒng)計(jì)完全一樣。對于JVM來說還不錯(cuò),但比Golang版本多了近6倍。

啟動時(shí)間

Golang和cloud-native java都能立即啟動,然而JVM版本需要幾秒鐘(取決于分配的CPU),并且在啟動時(shí)產(chǎn)生CPU峰值。如果配置不當(dāng),會導(dǎo)致k8s HPA發(fā)飆,并增加pods。

開發(fā)體驗(yàn)

這與其說是一個(gè)實(shí)際問題,不如說是一個(gè)宗教問題。Quarkus 使用了在 Java 世界中很常見的抽象(比如基于注解的DI)。它為你啟動服務(wù)并創(chuàng)建連接池。它可以使用豐富的集合標(biāo)準(zhǔn)庫和generics。然而,這可能感覺有點(diǎn)像黑魔法,一旦有些組件不工作,你會感覺很無助。此外,將 Java 代碼編譯成原生二進(jìn)制并不是那么簡單,有一些限制和注意事項(xiàng)是你必須知道的,并非每個(gè)Java庫都能兼容原生編譯。一旦使用一個(gè)不兼容的庫(比如Guice),你就需要自己配置Graal VM。

Quarkus 和 Graal VM "相對 "較新。所以可能會有一些問題。但由于雙模式(JVM或原生)。在原生版本的某些組件停止工作的情況下,總是有一個(gè)后備方案,這對任何新問題來說都是很好的變通方法。

另一方面,Golang 在成立10年后才承認(rèn)它需要generics。而且它肯定不喜歡框架使用很多魔法操作。這在很多方面既是好事也是壞事。此外,盡管 Go 社區(qū)做的非常好,然而可用的工具和庫還是相對較少。然而它的編譯和構(gòu)建過程更快/更簡單。而且兼容每個(gè)Golang的包,沒有java-native平臺帶來的限制。

結(jié)論

Java已經(jīng)為云原生做好了準(zhǔn)備,Golang并沒有大幅度領(lǐng)先。相信未來Cloud Native Java會被大規(guī)模使用。

 

原文地址:https://medium.com/swlh/cloud-native-java-vs-golang-2a72c0531b05

本文轉(zhuǎn)載自微信公眾號「高可用架構(gòu)」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系Igor Domrev 公眾號。 

 

責(zé)任編輯:武曉燕 來源: 高可用架構(gòu)
相關(guān)推薦

2019-09-20 13:37:50

Java云原生Docker

2025-06-04 10:08:00

Go開發(fā)云原生

2021-08-09 11:43:02

容器云原生安全

2023-08-28 16:08:12

2020-08-28 08:29:40

云原生微服務(wù)編程

2022-06-22 09:24:30

云原生Go 語言

2019-07-04 17:28:04

騰訊云云原生開源

2020-10-21 10:04:56

云原生應(yīng)用架構(gòu)

2020-12-01 17:44:15

華為云Go語言云原生

2021-08-23 13:50:46

云原生PaaS

2022-05-26 11:50:15

云原生云安全

2021-03-23 11:09:36

云計(jì)算

2022-01-14 07:17:39

阿里云云原生經(jīng)濟(jì)

2012-09-26 10:59:52

大數(shù)據(jù)云計(jì)算云服務(wù)

2021-12-08 12:03:09

金融科技云原生

2023-11-30 16:42:21

2022-10-27 18:03:04

GogRPC云原生

2022-11-30 18:38:50

2018-11-19 15:14:36

華為云
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 久久国产精品99久久久久 | 美女在线观看国产 | 午夜精品| 91国产在线播放 | 一区二区国产精品 | 日韩高清国产一区在线 | 黄色片在线 | 欧美影院 | 欧美一a一片一级一片 | 国产精品一区二区福利视频 | 亚洲日本欧美日韩高观看 | 日本中文字幕日韩精品免费 | 成人影院午夜 | 九九热在线观看视频 | 日本久久www成人免 成人久久久久 | 99精品网| 午夜久久久 | 精品久久99 | 91成人精品| 视频一区在线播放 | 久草免费福利 | 国产精品免费高清 | 日日噜噜噜夜夜爽爽狠狠视频97 | 福利片在线看 | 亚洲毛片 | 黄色网络在线观看 | 国产精品美女久久久 | 欧美日韩在线一区二区 | 亚洲一区二区视频在线观看 | 亚洲草草视频 | 日韩一级黄色片 | 新91视频网 | 久久久久免费 | 伊人最新网址 | 伊人影院在线观看 | 老头搡老女人毛片视频在线看 | av一区二区三区四区 | 久久久精品在线 | 国产a级毛毛片 | 在线播放中文字幕 | 国产精品日产欧美久久久久 |