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

云原生時代,Java還是Go?

開發 后端 云原生
Java曾經著名的座右銘:"一次編寫,到處運行",已經很過時了,因為現在我們只想在容器里運行代碼。在容器里,一個 "Just in time "的編譯器意義不大。

Java曾經著名的座右銘:"一次編寫,到處運行",已經很過時了,因為現在我們只想在容器里運行代碼。在容器里,一個 "Just in time "的編譯器意義不大。

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

 

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

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

Java有機會嗎,也許只有時間才會告訴我們最終答案。然而,出于好奇,我想從性能和開發體驗方面比較一下 Java 和 Golang 的云原生服務。

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

對于我的案例來說,這是一個 "足夠好 "的基準,因為我不假設找到最好/最差的基準結果,而是在同一環境下執行運行兩個基準測試進行比較。

場景

這兩個服務將連接到在另一個容器中運行的MySQL數據庫,有一個表和三行數據。

 

每一個服務都會獲取所有記錄,將它們轉化為對象,然后輸出JSON數組。

ab將發出10K請求,并發級別為100,quarkus JVM版本運行兩次(用于測試 "冷"/"暖 "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驅動的使用go-sql-driver。golang的代碼風格是非常明確的。一種一切都在眼前態度。主函數啟動服務器,配置請求處理程序,打開DB連接。

編譯本地可執行文件

 

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.     } 

數據庫連接使用Quarkus React Mysql 擴展。

 

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

這里使用Netty響應式web服務器,由Vert.x多事件循環包裝,還有一個Vert.x響應式MySQL驅動,這樣可以用一個線程處理多個DB連接。

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

編譯Java版本的可執行文件

 

我已經弄清楚構建過程中發生了什么,其核心是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
  • 吞吐量(每秒請求數)

測試結果

 

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

延遲和吞吐量

Golang 和原生 Java 的測試結果比較接近,雖然平均來說 Golang 版本的測試結果略好一些。不過,Java Native版本的測試結果更穩定。Golang服務有時在1.25μ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已經為云原生做好了準備,Golang并沒有大幅度領先。相信未來Cloud Native Java會被大規模使用。

 

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

本文轉載自微信公眾號「高可用架構」,可以通過以下二維碼關注。轉載本文請聯系Igor Domrev 公眾號。 

 

責任編輯:武曉燕 來源: 高可用架構
相關推薦

2019-09-20 13:37:50

Java云原生Docker

2025-06-04 10:08:00

Go開發云原生

2023-08-28 16:08:12

2020-08-28 08:29:40

云原生微服務編程

2021-08-09 11:43:02

容器云原生安全

2019-07-04 17:28:04

騰訊云云原生開源

2022-06-22 09:24:30

云原生Go 語言

2020-10-21 10:04:56

云原生應用架構

2021-08-23 13:50:46

云原生PaaS

2022-05-26 11:50:15

云原生云安全

2022-01-14 07:17:39

阿里云云原生經濟

2020-12-01 17:44:15

華為云Go語言云原生

2021-03-23 11:09:36

云計算

2012-09-26 10:59:52

大數據云計算云服務

2023-11-30 16:42:21

2021-12-08 12:03:09

金融科技云原生

2022-11-30 18:38:50

2022-10-27 18:03:04

GogRPC云原生

2018-11-19 15:14:36

華為云
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲精品一区二区三区蜜桃久 | 欧美一区永久视频免费观看 | 欧美一二三区 | 精品视频一区二区三区在线观看 | 久久se精品一区精品二区 | 精品一区二区三区在线观看国产 | 999久久久| 日韩亚洲视频 | 一区二区三区韩国 | 在线成人 | 久草精品视频 | 国产亚洲精品美女久久久久久久久久 | 久久久久久国产 | 操视频网站 | 羞羞视频一区二区 | 一区二区在线观看av | 亚洲天堂男人的天堂 | 日本亚洲精品成人欧美一区 | 久久精品亚洲精品国产欧美 | 99久久免费精品 | 成人在线免费视频 | 日韩和的一区二在线 | 日本精品一区二区三区在线观看 | 成人在线一区二区 | 国产精品国产成人国产三级 | 久久成人精品一区二区三区 | 午夜影视 | 国产欧美精品区一区二区三区 | 精品福利在线 | 亚洲国产成人精品女人久久久 | 天堂成人国产精品一区 | 亚洲精品黄色 | 国产区精品视频 | 亚洲成人av在线播放 | 欧美精品综合在线 | 91av导航| 黄色网址免费在线观看 | 91www在线观看 | 午夜精品一区 | 精品欧美色视频网站在线观看 | 日本网站在线看 |