顛覆微服務(wù)架構(gòu)?谷歌最新開源Service Weaver初體驗(yàn)
本文轉(zhuǎn)載自微信公眾號「涼涼的知識庫」,作者涼涼的知識庫 。轉(zhuǎn)載本文請聯(lián)系涼涼的知識庫公眾號。
合久必分,分久必合,技術(shù)圈也是如此。在大家紛紛從單體應(yīng)用過渡到微服務(wù)的時(shí)候,谷歌攜帶著新時(shí)代的“單體”應(yīng)用框架Service Weaver來了!代碼倉庫位于:https://github.com/ServiceWeaver/weaver 才發(fā)布沒幾天已經(jīng)超過了2.5k star,不得不感慨谷歌的號召力。
谷歌稱此框架為模塊化單體(modular monolith),谷歌為什么會在這個(gè)時(shí)候提出如此標(biāo)新立異的框架?它究竟有什么獨(dú)特之處?讓我們來速速體驗(yàn)下吧。
安裝
因?yàn)镾ervice Weaver使用了泛型,且聲明的依賴版本為1.19。所以本地安裝的go版本需要大于1.19
如果你設(shè)置了正確的$GOPATH/bin路徑到你的PATH中那么你可以直接運(yùn)行
教程
創(chuàng)建項(xiàng)目
啟動服務(wù)
先來創(chuàng)建一個(gè)最簡單的HTTP服務(wù)。與Go內(nèi)置的HTTP server的使用方式非常類似,唯一的區(qū)別是創(chuàng)建端口監(jiān)聽的方式不同,Service Weaver需要使用github.com/ServiceWeaver/weaver包提供的函數(shù)來創(chuàng)建監(jiān)聽
執(zhí)行也和普通的代碼沒有區(qū)別
當(dāng)服務(wù)啟動之后我們就可以調(diào)用對應(yīng)端口,直到這里依舊和普通的HTTP server沒有區(qū)別
組件(Components)
組件是Service Weaver中一個(gè)獨(dú)特的概念
什么是組件?一個(gè)應(yīng)用會有多個(gè)組件,每一個(gè)組件就是一個(gè)Go的interface。
下面的反轉(zhuǎn)字符串type Reverser interface就是一個(gè)組件,type reverser struct是它的一個(gè)實(shí)現(xiàn)。需要注意一點(diǎn)reverser struct組合了weaver.Implements[Reverser]用以實(shí)現(xiàn)Service Weaver要求的其他接口
組件該怎么用?我們可以用weaver.Get()獲取一個(gè)組件的實(shí)例。例如:
這次在運(yùn)行代碼前我們得先執(zhí)行下面命令,文件中會多一個(gè) weaver_gen.go 文件
重新運(yùn)行代碼
調(diào)用對應(yīng)的接口就會獲得反轉(zhuǎn)的字符串響應(yīng)
對組件的看法
組件的概念,給我的第一感覺是非常像依賴注入中的IOC容器(不知道什么IOC的同學(xué)可以自行網(wǎng)上搜索充電)。
很多語言的很多框架都有依賴注入的功能:定義一個(gè)接口,實(shí)現(xiàn)這個(gè)接口,從IOC容器中獲取這個(gè)接口的實(shí)例。借助依賴注入來實(shí)現(xiàn)依賴解耦,簡化對象創(chuàng)建流程等
Service Weaver定義組件的概念也有其自身的目的,稍后體驗(yàn)過多進(jìn)程執(zhí)行的之后,會對組件有一點(diǎn)更深的理解
多進(jìn)程執(zhí)行
先創(chuàng)建一個(gè)TOML文件weaver.toml,內(nèi)容如下
編譯并使用weaver multi deploy來運(yùn)行我們的應(yīng)用
調(diào)用對應(yīng)的接口依舊會獲得反轉(zhuǎn)的字符串響應(yīng)
你可能會說這和go run .有啥區(qū)別?對于返回的響應(yīng)來說確實(shí)沒有區(qū)別,但在運(yùn)行機(jī)制上兩者已經(jīng)有了巨大的差別。
當(dāng)我們執(zhí)行g(shù)o run .時(shí),我們的應(yīng)用包含所有的組件運(yùn)行在一個(gè)進(jìn)程中,組件的調(diào)用就是Go中的正常的函數(shù)調(diào)用
當(dāng)我們執(zhí)行weaver multi deploy weaver.toml時(shí),我們的應(yīng)用中的組件會變的像微服務(wù)一樣,運(yùn)行中多個(gè)進(jìn)程中,此時(shí)組件的調(diào)用就通過RPC的方式了
更進(jìn)一步,既然組件都可以運(yùn)行中在不同的進(jìn)程中,自然也可以運(yùn)行在不同的機(jī)器中
Service Weaver目前僅提供了GKE(Google Kubernetes Engine)的支持。快速將應(yīng)用部署到GKE的不同容器中
對多進(jìn)程的看法
此時(shí)再回顧下對組件的看法,weaver.Get:當(dāng)單進(jìn)程部署時(shí),它返回一個(gè)接口的本地實(shí)例,當(dāng)多進(jìn)程部署時(shí),它返回一個(gè)RPC的client
Service Weaver稱自己為模塊化單體(modular monolith)。通過組件這個(gè)概念讓你寫代碼和部署代碼的動作分離開,你可以按照單體的方式寫代碼,然后在其他進(jìn)程或者機(jī)器按照微服務(wù)的方式運(yùn)行組件的進(jìn)程
總結(jié)
因?yàn)橐彩莿倓偨佑|到這個(gè)框架,很多細(xì)節(jié)還不太理解,目前業(yè)界更是沒有實(shí)踐落地。這里說些我自己的看法,也歡迎大家批評指正
單體向微服務(wù)的演進(jìn)不是由于某個(gè)單一的原因造成,團(tuán)隊(duì)的分工,龐大的代碼,復(fù)雜的依賴等諸多原因造就了現(xiàn)在流行微服務(wù)架構(gòu)。Service Weaver也并沒有要取代傳統(tǒng)微服務(wù),在不同團(tuán)隊(duì)間使用傳統(tǒng)微服務(wù),在同一個(gè)團(tuán)隊(duì)內(nèi)部或者同一功能的服務(wù)使用模塊化單體是一種新的選擇
?? 關(guān)于模塊化單體(modular monolith)中的單體
單體的開發(fā)確實(shí)會降低我們的心智負(fù)擔(dān),我們不用關(guān)心不同模塊之間的RPC協(xié)議,模塊之間的服務(wù)發(fā)現(xiàn),在本地測試的時(shí)候也不需要專門構(gòu)建其他依賴微服務(wù)的模塊
Monorepo 倉庫能到達(dá)一樣的效果么?部分能,我們可以把一套微服務(wù)放到一個(gè)Monorepo中,并使用一個(gè)BFF服務(wù)對外提供統(tǒng)一的訪問入口,能實(shí)現(xiàn)類似于單體開發(fā)的體驗(yàn)。但我們依舊需要關(guān)心RPC協(xié)議、服務(wù)發(fā)現(xiàn)等一系列的問題
?? 關(guān)于模塊化單體(modular monolith)中的模塊
有了Service Weaver我們就可以不用關(guān)心服務(wù)拆分了么?不是的,我們依舊面臨著服務(wù)拆分,傳統(tǒng)的微服務(wù)拆分到不同的代碼倉庫,Service Weaver拆分到了不同的邏輯(組件)。所以傳統(tǒng)的服務(wù)拆分的方法論和經(jīng)驗(yàn),在這里依舊適用
?? 模塊化單體(modular monolith)之外的東西
Service Weaver也提供了Logging、Metrics、Tracing、Profiling的基本能力,這部分沒啥特殊的,絕大部分的RPC框架都集成了類似的能力
Service Weaver提供了Google Kubernetes Engine (GKE) 部署的能力,如果你的公司恰好使用標(biāo)準(zhǔn)的k8s服務(wù),或許不難擴(kuò)展。如果你的公司使用了非標(biāo)準(zhǔn)的k8s,如何與現(xiàn)有的部署系統(tǒng)結(jié)合也是個(gè)需要考慮的問題