Java微服務 vs Go微服務,究竟誰更強!?

點擊上方藍色「 方誌朋 」,選擇「設爲星標」

回覆「666」獲取獨家整理的學習資料!java



前言

Java微服務能像Go微服務同樣快嗎?這是我最近一直在思索地一個問題。linux

去年8月份的the Oracle Groundbreakers Tour 2020 LATAM大會上,Mark Nelson和Peter Nagy就對此作過一系列基礎的的測試用以比較。接下來就給你們介紹下。git

如下內容與觀點主要源自 https://medium.com/helidon/can-java-microservices-be-as-fast-as-go-5ceb9a45d673

在程序員圈子裏,廣泛的見解是Java老、慢、無聊 ,而Go是快、新、酷程序員

爲了儘量的進行一個相對公平的測試,他們使用了一個很是簡單的微服務,沒有外部依賴關係(好比數據庫),代碼路徑很是短(只是操縱字符串),使用了小型的、輕量級的框架(Helidon for Java和Go工具包for Go),試驗了不一樣版本的Java和不一樣的jvm。github

對決雙雄

咱們先來看下擂臺兩邊的選手:算法

  • 身穿深色戰服的選手是 JAVA

Java是由被甲骨文收購的Sun Microsystems開發的。它的1.0版本是1996年發佈的,最新的版本是2020年的Java15。主要的設計目標是Java虛擬機和字節碼的可移植性,以及帶有垃圾收集的內存管理。它是全世界最流行的語言之一,在開源環境下開發。數據庫

咱們先看下JAVA的問題,你們廣泛認爲它最大的問題就是速度慢,已經慢到讓人以爲再也不是合理的,而是更具歷史意義的。不過這麼多年來,Java誕生了不少不一樣的垃圾收集算法用來加快它運行的速度。微信

Oracle實驗室最近已經開發了一個新的Java虛擬機GraalVM,它有一個新的編譯器和一些使人興奮的新特性,好比可以將Java字節碼轉換成一個本機映像,能夠在沒有javavm的狀況下運行等。網絡

  • 而它的對手就是年輕充滿活力的 GO

GO是由谷歌的羅伯特·格里默、羅伯·派克和肯·湯姆森建立的。他們對UNIX、B、C、Plan九、UNIX窗口系統等作出了重大貢獻。GO是開源的,在2012年發佈了1.0版本(比JAVA晚了16年),在2020年發佈了1.15版本。不管是在採用方面,仍是在語言和工具生態系統自己方面,它都在快速增加。數據結構

GO受C、Python、JavaScript和C++等多種語言的影響。被設計成高性能網絡和多處理的最佳語言。

StackOverflow有27872個關於Go的問題,而Java卻有1702730個。足見長Java生態的強大。

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同樣快,或者更快

最後

接下來會作更多的測試比賽,來看一看究竟誰更好!

有興趣的你也能夠本身試一試,記得告訴咱們結果哦!

昨晚逛GitHub,無心中看到一位大佬(https://github.com/halfrost)的算法刷題筆記,感受發現了寶藏!有些小夥伴可能已經發現了,但咱這裏仍是忍不住安利一波,怕有些小夥伴沒有看到。

關於算法刷題的困惑和疑問也常常聽朋友們說起。這份筆記裏面共包含做者刷LeetCode算法題後整理的數百道題,每道題均附有詳細題解過程。不少人表示刷數據結構和算法題效率不高,甚是痛苦。有了這個筆記的總結,對校招和社招的算法刷題幫助之大不言而喻,果斷收藏了。

須要刷題筆記PDF文檔的小夥伴能夠直接長按掃碼關注下方二維碼,回覆 「 刷題筆記」 四個字自取:

關注下方公衆號

👇👇👇

回覆關鍵字「刷題筆記」,便可下載

筆記版權歸原做者全部,轉載請註明出處 https://books.halfrost.com/leetcode/

本文分享自微信公衆號 - 方誌朋(walkingstory)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索