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

itread01 2021-01-14 20:22:52
java vs 微服 究竟


### 前言Java微服務能像Go微服務一樣快嗎?這是我最近一直在思索地一個問題。去年8月份的the Oracle Groundbreakers Tour 2020 LATAM大會上,Mark Nelson和Peter Nagy就對此做過一系列基礎的的測試用以比較。接下來就給大家介紹下。在程式設計師圈子裡,普遍的看法是Java**老、慢、無聊** ,而Go是**快、新、酷**為了儘可能的進行一個相對公平的測試,他們使用了一個非常簡單的微服務,沒有外部依賴關係(比如資料庫),程式碼路徑非常短(只是操縱字串),使用了小型的、輕量級的框架(Helidon for Java和Go工具包for Go),試驗了不同版本的Java和不同的jvm。### 對決雙雄我們先來看下擂臺兩邊的選手:- 身穿深色戰服的選手是**JAVA**> Java是由被甲骨文收購的Sun Microsystems開發的。它的1.0版本是1996年釋出的,最新的版本是2020年的Java15。主要的設計目標是Java虛擬機器和位元組碼的可移植性,以及帶有垃圾收集的記憶體管理。它是全世界最流行的語言之一,在開源環境下開發。我們先看下JAVA的問題,大家普遍認為它最大的問題就是速度慢,已經慢到讓人覺得不再是合理的,而是更具歷史意義的。不過這麼多年來,Java誕生了很多不同的垃圾收集演算法用來加快它執行的速度。Oracle實驗室最近已經開發了一個新的Java虛擬機器GraalVM,它有一個新的編譯器和一些令人興奮的新特性,比如能夠將Java位元組碼轉換成一個本機映像,可以在沒有javavm的情況下執行等。- 而它的對手就是年輕充滿活力的**GO**> GO是由谷歌的羅伯特·格里默、羅伯·派克和肯·湯姆森建立的。他們對UNIX、B、C、Plan9、UNIX視窗系統等做出了重大貢獻。GO是開源的,在2012年釋出了1.0版本(比JAVA晚了16年),在2020年釋出了1.15版本。無論是在採用方面,還是在語言和工具生態系統本身方面,它都在快速增長。GO受C、Python、JavaScript和C++等多種語言的影響。被設計成高效能網路和多處理的最佳語言。StackOverflow有27872個帶“Go”的問題,而Java只有1702730個。足見長江後浪推前浪。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應用程式。結果如下:![file](https://img2020.cnblogs.com/other/626506/202101/626506-20210114155127604-1180639219.png)![file](https://img2020.cnblogs.com/other/626506/202101/626506-20210114155127767-1744939980.png)可以看出,第一回合是Go贏了!JAVA佔的記憶體太多了;預熱對JVM有很大的影響—我們知道JVM在執行時會進行優化,所以這是有意義的在第一回合的基礎上,意猶未盡的又引入GraalVM映像以使 Java 應用程式的執行環境更接近於 Go 應用程式的環境,添加了 GraalVM 映像測試(用 GraalVM EE 20.1.1ー JDK 11構建的本機映像)的結果是:![file](https://img2020.cnblogs.com/other/626506/202101/626506-20210114155128079-1186522273.png)![file](https://img2020.cnblogs.com/other/626506/202101/626506-20210114155128423-207029454.png)通過使用 GraalVM 映像在 JVM 上執行應用程式,我們沒有看到吞吐量或響應時間方面的任何實質性改進,但是記憶體佔用的確變小了。下面是一些測試的響應時間圖:![file](https://img2020.cnblogs.com/other/626506/202101/626506-20210114155129035-1935501481.png)#### 第二回合在第二輪測試中,使用一臺更大的機器上執行測試。36核(每個核兩個執行緒)、256GB記憶體、執行oraclelinux7.8的機器。和第一輪類似,使用了100個執行緒,每個執行緒使用了10,000個迴圈,10秒的加速時間,以及相同版本的 Go,Java,Helidon 和 GraalVM。結果如下:![file](https://img2020.cnblogs.com/other/626506/202101/626506-20210114155129423-9183718.png)這一回合是GraalVM 映像贏了!下面是一些測試的響應時間圖:![file](https://img2020.cnblogs.com/other/626506/202101/626506-20210114155129867-1575449173.png)![file](https://img2020.cnblogs.com/other/626506/202101/626506-20210114155130342-589987172.png)![file](https://img2020.cnblogs.com/other/626506/202101/626506-20210114155130712-1279765043.png)在這個測試中,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結果如下:![file](https://img2020.cnblogs.com/other/626506/202101/626506-20210114155131033-820424159.png)下面是一些測試的響應時間圖:![file](https://img2020.cnblogs.com/other/626506/202101/626506-20210114155131420-1181988396.png)在這一輪中,我們觀察到 Go 有時更快,GraalVM 映像有時更快,但這兩者之間的差別很小(通常小於5%)。Java似乎比Go更善於使用所有可用的核心/執行緒—我們在Java測試中看到了更好的CPU利用率。Java效能在擁有更多核心和記憶體的機器上更好,Go效能在較小/功能較弱的機器上更好。在一臺“生產規模”的機器上,Java很容易就和Go一樣快,或者更快### 最後接下來會做更多的測試比賽,來看一看究竟誰更好!有興趣的你也可以自己試一試,記得告訴我們結果哦!本文參考:https://medium.com/helidon/can-java-microservices-be-as-fast-as-go-5ceb9a45d673> 歡迎關注我的公眾號:程式猿DD,獲得獨家整理的免費學習資源助力你的Java學習之路!另每週贈書不停哦~
版权声明
本文为[itread01]所创,转载请带上原文链接,感谢
https://www.itread01.com/content/1610626264.html

  1. springboot异常处理之404
  2. Spring boot security international multilingual I18N
  3. Spring boot exception handling 404
  4. Netty系列化之Google Protobuf编解码
  5. Netty之编解码
  6. Java编解码
  7. Netty解码器
  8. Netty与TCP粘包拆包
  9. Netty开发入门
  10. Java集合遍历时遇到的坑
  11. Spring IOC 源码解析(下)
  12. Spring IoC源码解析(上)
  13. Google protobuf codec of netty serialization
  14. Encoding and decoding of netty
  15. Java codec
  16. Netty decoder
  17. Netty and TCP packet sticking and unpacking
  18. Introduction to netty development
  19. Problems encountered in Java collection traversal
  20. Spring IOC source code analysis (2)
  21. Spring IOC source code analysis (Part one)
  22. 半小时用Spring Boot注解实现Redis分布式锁
  23. Implementing redis distributed lock with spring boot annotation in half an hour
  24. What should we do if we can't get tickets for Spring Festival transportation? You can solve this problem by using these ticket grabbing apps!
  25. 百度智能(文本识别),API传图OC代码与SDK使用
  26. springboot源码解析-管中窥豹系列之aware(六)
  27. Baidu intelligent (text recognition), API map, OC code and SDK
  28. Spring boot source code analysis
  29. springboot源码解析-管中窥豹系列之aware(六)
  30. 百度智能(文本识别),API传图OC代码与SDK使用
  31. Spring boot source code analysis
  32. Baidu intelligent (text recognition), API map, OC code and SDK
  33. Java学习笔记
  34. Java learning notes
  35. Sentry(v20.12.1) K8S 雲原生架構探索, SENTRY FOR JAVASCRIPT 手動捕獲事件基本用法
  36. 我的程式設計師之路:自學Java篇
  37. SpringBoot專案,如何優雅的把介面引數中的空白值替換為null值?
  38. Sentry (v20.12.1) k8s cloud native architecture exploration, sentry for JavaScript manual capture event basic usage
  39. My way of programmer: self study java
  40. Spring boot project, how to gracefully replace the blank value in the interface argument with null value?
  41. Redis 用的很溜,了解过它用的什么协议吗?
  42. Redis is easy to use. Do you know what protocol it uses?
  43. 《零基础看得懂的C++入门教程 》——(10)面向对象
  44. Introduction to zero basic C + + (10) object oriented
  45. HTTP status code and troubleshooting
  46. Java NIO之Channel(通道)入门
  47. Introduction to Java NiO channel
  48. Spring中的@Valid 和 @Validated注解你用对了吗
  49. Are you using the @ valid and @ validated annotations correctly in spring
  50. Spring中的@Valid 和 @Validated注解你用对了吗
  51. Are you using the @ valid and @ validated annotations correctly in spring
  52. Redis | 慢查询
  53. Redis | slow query
  54. RabbitMQ一个优秀的.NET消息队列框架
  55. Autofac一个优秀的.NET IoC框架
  56. 如何使用Redis实现分布式缓存
  57. Rabbitmq an excellent. Net message queue framework
  58. Autofac is an excellent. Net IOC framework
  59. How to use redis to realize distributed cache
  60. JDK1.7-HashMap原理