這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
Go微服務理論基礎介紹
藍圖概述
是我們整個系列文章中構建的系統藍圖整體視圖。然而,我們將從頭開始寫我們的第一個Go微服務,然後當我們沿著部落格系列的各部分進展時,我們將會越來越接近下面的圖所代表的結構。
圖例基本如下:
- 虛線白框: 在一個或多個節點上啟動並執行邏輯Docker Swarm叢集。
- 藍色框: 來自Spring Cloud/Netflix OSS棧或其他服務例如Zipkin的支援服務。
- 沙色/白盒: 實際的微服務。
它或多或少和Magnus Larssons微服務部落格系列中使用的藍圖相同,主要區別在於實際微服務是使用Go嵌入Java來實現的。qutoes-service是一個例外,它為我們提供了基於JVM的微服務, 我們可以用於和我們的基於Go的微服務的無縫整合對比以及測試平台。
理論基礎: 運行資訊
有人會問,為什麼我們要使用Go來寫微服務呢? 除了可以使用這麼有趣和具有創造性的語言幹活之外,使用Go構建微服務的主要理由是具有微小的記憶體佔用。讓我們看看下面的,我們正運行在Docker Swarm下的Go微服務以及基於Spring Bot和Spring Cloud架構的微服務。
quotes-service是Spring啟動的,而compservice和accountservice是基於Go的。兩者都是使用大量類庫部署和Spring Cloud基礎設施整合起來用於處理HTTP的伺服器。
2017年真的重要嗎? 看看Java實現的微服務和Go實現的微服務所佔的記憶體大小,就會讓我們感覺到吃驚, 相差幾十倍。確實如此,對於大型企業來說,運行數十個服務都是少的,很多公司會運行成千上萬的放在雲提供上的微服務。當我們運行大量的容器,節約資源會為公司節省大量的資金。
微服務的非功能性需求
本文不僅僅是關於如何使用Go語言構建微服務的 - 它同樣是一個在Spring Cloud環境中表現良好的,並且是符合一個生產就緒的微服務領域所需要的品質。
考慮如下(順序無特殊考慮):
- 集中化配置: Centralized configuration.
- 服務發現: Service Discovery.
- 日誌: Logging.
- 分布式跟蹤: Distributed Tracing.
- 斷路器: Circuit Breaking.
- 負載平衡: Load balancing.
- 邊界: Edge.
- 監控: Monitoring.
- 安全: Security.
所有這些東西我認為當你決定嘗試微服務的時候都需要考慮的,而不用管你具體使用Go語言、Java語言、js、python、C#還是其他你喜歡的語言來編碼。這個部落格序列我們從Go語言的視角來揭示所有的這些話題。
另外一個視角是在你實際的微服務實現中的東西。不管你來自什麼語言,你都可能有提供了如下功能的類庫:
- HTTP/RPC/REST/SOAP/諸如此類的API.
- 持久化API(DB用戶端、JDBC、O/R映射).
- 訊息API(MQTT、AMQP、JMS).
- 可測試性(單元測試/整合測試/系統測試/驗收測試).
- 構建工具(CI/CD)
- 更多...
我不會涵蓋這些話題的所有內容。如果我要這麼做,我將會寫一本書而不是部落格系列文章。我將涵蓋它們中的一小部分。
在Docker Swarm模式下運行
這些文章系列中的系統領域的基本前提是我們的運行環境是Docker Swarm。意思就是所有服務 - 支援服務(設定管理員、邊界服務等)或實際微服務實現都是部署為Docker Swarm服務中的。 當我們到文章序列末尾的時候,有如下Docker命令:
再次請注意,上面列舉的服務包含了我們在第五部分設定我們的Swarm陣列的時候會包含的很多服務。
效能
好吧 - 因為Go微服務佔用很小的記憶體資訊 - 但是它們能執行嗎? 有意圖的對標不同程式設計語言是非常難的。也就是說, 如果我們拿例如benchmarkgame這樣的網站來看,人們可以提交明確演算法的各種語言中的實現, 然後互相進行效能比較,Go語言一般稍微比Java 8快些,稍微有點意外。 Go語言實際通常和C++對比稍微慢一點,只是基於一些基準測試情境而言。也就是說, Go語言對於一般的微服務工作負載來說執行很好 - 服務HTTP/RPC, 序列化/還原序列化資料結構, 處理網路I/O等等。
Go語言另外一個特別重要的屬性就是它具有記憶體回收機制的語言。在Go 1.5的記憶體回收主要重寫之後,GC暫停一般幾乎應該就幾毫秒的樣子。如果你來自JVM世界(我自己就是),Go語言的記憶體回收行程可能還不是那麼成熟,但是在Go 1.2以後引入的一些改變讓它似乎已經非常可靠了。這也是一個不可配置的奇蹟--也有一個球形把手(GOGC), 你可以微調Go語言中的GC行為, 可以控制相對可到達對象的總堆尺寸。
然而 - 跟蹤效能影響,因為我們將構建我們第一個微服務,並且添加諸如斷路器、跟蹤、日誌等東西到裡邊, 這樣可以非常有意思,因此我們在後面的文章中將使用Gatling測試, 來看我們不斷向微服務添加更多功能後的效能變化。
啟動時間
Go應用程式的另外一個好特點就是它啟動非常快。簡單的帶有一些路由、JSON序列化等的HTTP伺服器一般啟動時間最多100微秒。當我們在Docker容器中運行我們的Go微服務,我們可以看到它們健康的就緒服務最多數秒以內, 而我們相關的Spring Boot類型的微服務一般需要至少10秒才能就緒。雖然這不是最重要的特點,但是它肯定是有用的,當你的環境需要通過快速擴充來處理無法預料的大訪問量。
靜態連結二進位檔案
基於Go語言的Docker微服務的另外一個大好處是,我們可以在一個可執行二進位檔案中獲得靜態連結的二進位所有依賴關係。雖然檔案本身不是很緊湊(一個微服務一般來說具有10-20Mb的樣子), 最大的好處是我們能得到非常簡單的Dockerfile,並且我們可以使用非常裸露的基礎Docker映像。 我使用了一個基礎映像叫做iron/base, 它大概只有6MB。
FROM iron/baseEXPOSE 6868ADD eventservice-linux-amd64 /ENTRYPOINT ["./eventservice-linux-amd64", "-profile=test"]
換句話說就是 - 沒有JVM或其他運行時的必要組件, 除了標準C庫(libc)之外,都是包含在基本映像之中的。
我們將在後續文章中更加深入到如何構建我們的二進位以及-profile=test的一些東西。
總結
本篇文章中,我們介紹了一些使用Go語言構建微服務的一些關鍵因素: 例如記憶體資訊佔用少、良好的效能以及便捷的靜態連結二進位。
中英文對照
- 運行資訊: Runtime footprint, 參考連結: https://bbs.csdn.net/topics/4...。
- 單元測試: Unit Test.
- 整合測試: Integration Test.
- 系統測試: System Test.
- 驗收測試: Acceptance Test.
- 持續整合: Continuous Integration.
- 持續部署: Continuous Deployment.
參考連結
- Gatling test: Web應用程式的效能測試。
- 專題首頁
- 構建我們第一個Go語言微服務