這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
概覽
下面這張圖就是我們將要搭建的項目的概覽圖。我們將開始寫第一個微服務之後我們會一點點完成這張圖的所有內容。
講解:
白色虛線的方框內: docker swarm叢集,運行在一個或多個節點上。
藍色方框內: Spring cloud/Netflix OSS提供的支援系統,或者其他服務,比如zipkin
黃色方框/白色方框: 一個微服務。
運行資源消耗
為什麼我們要用go來寫微服務?除啦有意思和有效率,另一個主要原因是go在運行時消耗的記憶體非常小。下面這張圖對比了Spring boot,Spring cloud和go.(都是基於運行在docker swarm上的微服務)
quotes-service是基於spring boot.compservice和accountservice是基於go.兩個都是基於http伺服器並且有許多庫來和spring cloud整合。
但是記憶體消耗現在還要考慮嗎?我們現在不是有GB層級的RAM能輕鬆負載一個java應用嗎?
可以這麼說,但是對於一個大企業,他們不止運行幾十個微服務,甚者成百上千的微服務。這樣的話減少資源消耗就能省下很多錢。
來看一下亞馬遜主機的價格:
第二列為cpu數量,第四列為RAM大小。
我們看到當RAM增加一倍,價錢也隨著增加一倍。如果你的cpu足夠,就不必為缺少記憶體而要多花一倍的錢,後面我們也會看到go的服務在處理請求時甚至比spring boot 在閑置的時候少。
微服務非功能性要求
這篇部落格不僅僅關於go搭建微服務,更是如何在spring cloud環境下運行和搭建符合真正用於生產環境的微服務供應項目。包括:
- 中心化配置
- 服務發現
- 日誌
- 分布式探尋
- 熔斷
- 負載平衡
- 邊緣
- 監測
- 安全
這些內容都應該在為服務裡實現,不僅僅是用go,其他的語言,例如,java,python,寫微服務供應項目時也應該實現這些功能.在這篇部落格中我會盡量從go語言角度覆蓋這些內容。
另一方面要考慮的是關於微服務的實現,你可能聽過:
- HTTP/RPC/REST/SOAP/任何形式的APIS
- 持久化資料的API (DB clients, JDBC, O/R mappers)
- 訊息處理API (MQTT, AMQP, JMS)
- 測試 (單元測試,integration, system, acceptance test)
- 編譯工具/CI/CD
我會講解這其中的一些。
在docker swarm上運行
概覽中我們看到我們的服務會運行在docker swarm中,這意味著我們所有的服務,包括支援服務(伺服器配置,邊緣等)和微服務程式都會運行在docker swarm中。在這個項目結束時,我們運行:
docker service ls
我們會看到下面這些服務
![圖片上傳中...]
注意:上面這些服務遠多於我們在第五章裡搭建的s
go微服務佔用很小的記憶體-但是效能怎麼樣?對程式設計語言做有意義的基測很難。從基測網站上提交的演算法上看,go比java8大部分時間會快。go大部分情況和c++差不多快,但在一些基測上,要慢很多。就是說,對於普通的微服務工作-負載HTTP/RPC,序列化/還原序列化資料結構,網路吞吐方面,go可以表現的不錯。
另一個重要的特性是go具有記憶體回收功能,在go 1.5GC的記憶體回收中只需要停頓幾微秒。go的記憶體回收也許不是那麼成熟,但是在1.2之後,他表現的很穩定。更為驚奇的是,你可以更改通過更改整個棧相對於類的大小,來更改記憶體回收的效能。
然而,我們在測試效能的同時會寫我們的第一個微服務,之後我們會加入熔斷,追蹤,日誌等功能。在我們加入越來越多的功能之後,我們會用Gatling來測試我們的效能。
啟動時間
另一個go的特性是它的啟動速度非常快。一個普通的HTTP伺服器加上一些路由和json序列化功能的服務在幾百毫秒就可以啟動。當我們在docker中運行時,我們可以運行它們在幾秒之內。然而,一個spring boot的微服務需要至少10秒。這個看起來好像沒什麼影響,但是在你需要快速應對大流量的處理時將會非常有用。
靜態連結二進位
另一個優點go的靜態連結的二進位包含所有的依賴在一個可執行檔二進位檔案中,我們可以把這個包放在docker容器中。同時這個檔案不大,一般來說10-20MB。這樣我們就能得到一個很簡單的dokerfile.我們可以用一個很基本的docker鏡像來開始。我用的是 iron/base,這個鏡像大約6MB。
FROM iron/baseEXPOSE 6868ADD eventservice-linux-amd64 \ENTRYPOINT ["./eventservice-linux-amd64", "-profile=test"]
換句話說,不需要JVM或者其他啟動並執行組件,只需要這個鏡像裡標準的c庫
我們之後會講解如何編譯二進位檔案和-profile=test是什麼意思。
總結
這篇部落格中,我們介紹為什麼要用go來做微服務。主要原因是:
- 小的記憶體消耗
- 效能良好
- 靜態連結二進位檔案的方便
下一篇文章中,我們會開始寫第一個微服務。