Go語言微服務實戰之初識微服務

現在有越來越多的公司將go語言做爲後臺開發的首選語言,另外在後臺開發中,微服務應該算得上是最流行的架構模式了,寫這個系列的文章,主要是對此前項目中的微服務實踐做個自我總結,因爲個人也是個初學者,在黑暗中摸索,所以如果文章中出現低級錯誤也請讀者勿要見笑,同時希望大神們不吝賜教。

本系列的文章,將圍繞搭建一個基於微服務架構的數據統計系統的實戰例子展開,我們將展示如何將服務運行在docker容器中,並將其部署在kubernetes上,相信看完這個系列的文章後,你也可以快速入門後臺開發。

在開始動手之前,咱們先用一篇文章簡單瞭解一下go語言和微服務。

1、爲什麼用go語言

越來越多的公司開始用go語言進行後臺開發,比如騰訊就在逐步的將後臺從C++向Go語言過渡。任何事情的發生背後都是有原因的,使用go語言開發服務端程序的最主要的原因應該是go具有支持大併發的基因。

1.1 天然的併發支持

瞭解過go語言的同學一定知道協程這個概念。相比線程而言,協程因爲可以免去線程切換時用戶態和內核態的切換,具有更高的性能,對併發的支持非常好,即便一個剛進入後臺開發的小白,用go語言也可以寫出支持幾十上百萬的程序。

1.2 編譯速度快

編譯速度對程序員來說一直是個繞不開的話題,大型的項目動不動就是幾個小時的編譯時間,本人至今還依稀記得編譯一次android源碼的酸爽。相較於其他語言,go語言的編譯速度快可以說是它的另一大優勢。

1.3 完備的垃圾回收機制

和Java一樣,go也有自身一套基於三色標記法的垃圾回收機制。對於用C++開發後臺的程序員來說這無疑是個福音。但凡寫過C++的一定對內存泄漏深有體會,即便有智能指針也不能避免,一個稍微大點的項目,內存問題排查起來費時費力,在這一點上,go的設計者吸納了Java GC的理念,用GC將開發者從手動管理內存分配釋放的苦惱中解脫出來(當然跟Java一樣,即使有垃圾回收,go也無法徹底避免內存泄漏)

1.4 簡單易學

go的關鍵字數量非常少,簡單易學,新手能夠快速入門。如果學C++,裏面隨便抽出一塊諸如STL之類的,估計都夠大部分人喝上一壺。go則不然,語法簡練,稍有編程基礎的人可以足夠快的入門。這也是go語言設計者的初衷之一:其他的語言是在不斷的向其中堆加新功能,而go語言則是做減法,取其精華去其糟粕。

瞭解了go,在回頭來看看微服務,這是目前後臺開發中比較流行的框架,對後臺開發有興趣的同學值得了解和學習。

2、初識微服務

2.1 單體架構

要想搞明白微服務,先得了解單體架構。一般小的公司在項目規模還不是很大的時候,爲了快速上線新功能,往往會採用這種架構。這種架構就跟它的名字一樣簡單易懂。

設想現在要做一個電商項目,可以創建訂單,驗證庫存,配送等等。因此在服務端可能由不同的模塊:用戶模塊,訂單模塊,物流配送模塊等等。

在單體架構模式下,將這些模塊都整合成爲一個整體部署進去,在加一個ngix反向代理做負載均衡就可以了,就向下面這張圖一樣:

一個Ngix反向代理服務器做負載均衡,一個數據庫,再加上一個打包運行在容器中的業務進程,這基本上就是單體架構的全部了。正如圖中所說的,這種架構的特點就是:開發、測試、部署和擴容都非常簡單,業務規模大了填機器就行了(這也是很多向我一樣沒有搞過後臺開發的人的幼稚思維:後臺不就是加機器就可以了嗎?)

單體架構的優點很明顯,但缺點也同樣明顯:

(1) 代碼庫龐大:所有的業務代碼都在一個工程中,隨着產品需求和功能的不斷堆加,代碼會變得越來越多並且難以維護;

(2) 模塊邊界模糊:很可能只是每個模塊僅僅用一個文件夾了事,但實際的依賴關係很難理清;

(3) 構建部署問題:每次修復一個問題,整個應用都需要重新打包部署。試想一下,因爲用戶模塊的一個小bug,就要重新打包部署整個應用,導致訂單等其他模塊在一段時間內也不可用,這對用戶體驗及其不友好;

(4) 阻礙技術創新:在單體應用下,整個團隊只能使用相同的技術棧,要麼大家都用Java,要麼大家都用C++,如果你想嚐鮮用用go,對不起,其餘人可能沒那麼多時間陪你玩。

總結起來一句話:項目規模小的時候,單體架構完全可以應付好一陣子,但是當規模上來以後,單體架構一定無法滿足需求。

2.2 微服務架構

說完了單體架構,再來說說微服務。微服務架構的哲學其實可以理解爲設計模式中的單一職責原則:只做一件事並將它做到極致。仍以上面的電商那個例子來看,在微服務架構模式下,可以拆分成用戶服務,訂單服務,物流服務等一個一個的微服務。這些微服務不在向單體那樣鐵板一塊,而是單獨部署。這就解決了前面提到的單體架構的一些痛點問題:

(1) 因爲微服務是單獨部署的,所以假如用戶服務出了問題,只需要修復問題以後重新部署用戶服務即可,其他服務依然可以對外提供服務;

(2) 模塊清晰:每個微服務就是一個獨立的功能模塊,微服務之間可以通過RPC的方式調用其依賴的服務;

(3) 技術棧可以異構:負責用戶服務的團隊用的是基於Java的Spring,而負責訂單服務的團隊可以用Go。

微服務架構雖然解決了單體架構的問題,但是隨之而來的一個無法迴避的問題就是服務與服務之間互相調用的問題。

因爲服務是單獨部署的,因此服務間要想相互調用只能通過RPC的方式:部署在機器A上的用戶服務通過RPC的方式調用部署在機器B上的訂單服務。這就引入了微服務架構中一個重要的組件:服務發現與註冊中心。你要調用訂單服務的接口,首先你得知道哪些機器上部署了訂單服務,註冊中心就是幹這個事的,所有的微服務都把自己註冊到註冊中心,這樣註冊中心就知道哪個服務在哪些機器上,當有調用請求的時候,由註冊中心按一定的負載均衡策略把這個請求落地到具體的機器上,下面是最能說明服務註冊中心的一張經典圖:

有好事的同學可能要問了:那註冊中心掛了咋辦?沒錯,註冊中心是大腦,腦死亡了當然不行,所以註冊中心在部署的時候肯定是要部署多臺機器做到高可用。

註冊中心作爲微服務架構中的核心組件,其本身的設計實現是很複雜的,目前常見的註冊中心有阿里開源的Nacos,ZooKeeper,Consful,Eureka等等,另外kubernetes也可以作爲註冊中心來使用。如果對註冊中心的實現感興趣,建議可以看看Nacos的代碼。

3 總結

go語言的特性:併發支持好、編譯快,簡單易上手,特別適合新手快速入門後臺開發;

單體架構的應用易於開發、測試和擴容,但是隨着項目規模越來越大將會越來越難維護,容易積累技術債,後期在想升級架構會付出很大的成本。

微服務架構解決了單體架構的痛點問題,足以應對大規模用戶量的場景。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章