首頁 > 軟體

「技術分享」Go真的比Java快嗎?來看看下面測試結果吧!

2021-05-30 11:30:43

研究早期的 Java/Go 基準測試

瞭解用 Java 和 Go 編寫的微服務之間的效能差異將幫助您規劃在構建自己的服務時選擇的語言。早些時候我在部落格上說 Go 比 Java 好,但它缺乏證據和資料點。我想從一些早期的工作開始,向我的同事證明 Go 和 Java 一樣快,並且可以快速啟動。速度對於無伺服器至關重要,因為該程序可以在不使用時停止並從冷狀態再次啟動以服務請求!因此,在dzone搜尋「Java Go」比較後,我驚訝地在結果頂部找到了 Ivan Nikitsenka(原作者)的一篇基準文章:

這得出結論,應用程式併發方面Java比Go快兩倍。什麼?真的嗎?!Java懶惰的即時編譯器是否可以比Go靜態二進位制檔案快?我可以重現他的結果嗎?

再現測試結果

感謝原作者,他釋出了他的Java和Golang應用程式的原始碼,以及他如何使用 Jmeter 進行測試、他的結果以及如何通過 Cloudformation在AWS的中立場地上運行它!

我在我的 T14s Thinkpad 本地運行它,與「springboot」Java 應用程式相比,Go 應用程式確實出錯了。儘管bank-go與 991MB 的影象大小相比,影象的重量為 10.2MB,bank-java並且在運行時消耗的資源要少得多:

為什麼 Go 變慢了?

我本能地認為資料庫連線一定是瓶頸。原作者的bank-go資料庫函數使用的是https://github.com/lib/pq#status,推薦使用pgx,積極維護。偉大的!我需要做的就是將資料庫驅動程式從pq切換到pgx。儘管更改了「sql.DB」類型相容 github.com/jackc/pgx/v4/stdlib ......負載測試時發生了相同類型的錯誤......

read tcp 127.0.0.1:XXXXX->127.0.0.1:5432: read: connection reset by peer #6

經過一番深思熟慮思考後,也許這與如何將連線彙集到資料庫有關。不幸的是,這意味著從 *sql.DB 重構到 *pgxpool.Pool需要新增上下文。

是的!錯誤消失了。它看起來也快得多。無論pgxpool(限制與資料庫的連線?)在做什麼,它似乎都在工作!

在我的 T14 上進行本地負載測試

Java 確實需要幾秒鐘才能在引擎蓋下生成機器程式碼……

使用hey load tester代替Jmeter:

在本地,我看到 Go 在大約 7457 個請求/秒和 Java 在大約 5758 個請求/秒加熱後。幾乎相同的。但是,我們應該在受控/可重現的環境中運行原作者的 jmeter 測試……進入雲。

在AWS 上進行 Go/Java 負載測試

存在三個潛在的瓶頸:

客戶端基準測試工具(以及網路)該應用程式資料庫

並且不要忘記 AWS 的 T 類型例項(虛擬機器)是突發性能例項,對於基準測試來說可能變化太大。

我決定將 m4.large 用於 bank-{app,db} 並在應用伺服器上運行原始 jmeter 基準測試並更新Cloudformation 以使用 AWS Linux ECS。請注意,我對資料庫的 IP 地址進行了硬編碼,因此您需要在自己重現結果時更改它。

我像這樣設定我的 ssh 公鑰:

aws --profile dev ec2 import-key-pair --key-name "hendry" --public-key-material fileb://~/.ssh/id_rsa.pub

因此,我的AWS基準測試工作流程類似於:

make delete — 拆除雲資源進行部署-在靜態IP上啟動應用程式和資料庫等待Java 版本的時間特別長——運行mvn似乎是它最重要的地方benchmark.sh 「測試名稱」

Go — 基準 1、基準 2、基準 3

Java — 基準 1、基準 2、基準 3

結論

Java 比 Go 需要更長的時間才能站起來 - 不是無伺服器的好選擇!儘管我沒時間了,但是像ALB健康檢查這樣的編排可以合併到堆棧中。這些例項構建了 Docker 映象,但它們何時準備就緒尚不清楚……對 bank-{go,java} 的重複測試導致沒有可用的檔案描述符耗盡,這似乎是 AWS ECS 問題通過 Cloudwatch 對例項的詳細監控過於粗糙,無法判斷資料庫是否是瓶頸……令人失望的DX。可能需要進一步的儀器來確定瓶頸所在Go 看起來更快一點,但是從冷啟動開始更穩定,99p 比 Java 的 >2000ms 低得多~100ms .. 但是,在某些運行時,我懷疑 Java 會更穩定。

不清楚原作者最初觀察到的錯誤是什麼,因為我認為這就是原作者錯誤地得出 Java 可以為兩倍的使用者提供服務的原因。在我的測試中,當我耐心等待 Java 服務準備就緒時,我可以在Go/Java 堆棧中運行測試而不會出錯,並且不會重複運行測試導致開啟檔案過多。

這裡推薦一本go語言相關微服務架構書籍《Go語言高併發與微服務實戰》近年來雲原生技術發展迅猛,幫助開發者在雲上快速和頻繁地構建、釋出和部署應用,以提高開發效率和快速定位故障。 微服務作為開展雲原生技術落地的核心,它將複雜的單體應用按照業務劃分並進行有效地拆分,每個微服務都可以進行獨立部署和開發,大大提升了應用開發效率。Go語言作為新生代的編譯型程式語言,具備語法簡單、高併發效能良好和編譯速度快等特點,是微服務架構落地實踐的絕妙利器。

原作者的 Go 程式碼似乎有一個數據庫連線池限制問題,在使用 pgxpool時消失了。

正如 Reddit /r/java和 YouTube 評論所暗示的那樣,對於大多數任務來說,Java 和 Go 在效能方面完全沒有問題。但是,我確實發現 Java 非常笨拙,支持者要求Java 預熱時間,這肯定會導致無伺服器冷啟動問題。相比之下,Go具有開箱即用的開發人員生產力和無伺服器友好的執行時間。

儘管如此,值得稱道的是,Java 框架的目標是使用GraalVM和 Quarkus 的提前編譯 (AoT)來降低啟動時間。很高興看到健康的競爭,儘管目前 Java 還有一些事情要做!


IT145.com E-mail:sddin#qq.com