微服務(wù)架構(gòu)可以視為面向組件架構(gòu)和面向服務(wù)架構(gòu)結(jié)合的產(chǎn)物。大多數(shù)和微服務(wù)相關(guān)的討論都是分析業(yè)務(wù)應(yīng)用如何微服務(wù)化,如何遠程調(diào)用,如何服務(wù)治理,談?wù)摶A(chǔ)設(shè)施服務(wù)的卻很少,本文內(nèi)容主要討論基礎(chǔ)設(shè)施服務(wù)的微服務(wù)過程,以及大家遇到的一些問題。
PS:以下是內(nèi)容來自于 GitChat 話題交流總結(jié),感謝主持人小媛子整理的問答精彩片段。
問:能說說創(chuàng)業(yè)小公司在微服務(wù)架構(gòu)設(shè)計中的經(jīng)驗嗎?在保證有限人力和敏捷開發(fā)的前提下,怎么設(shè)計一套自己的微服務(wù)體系?
答:說實話,微服務(wù)現(xiàn)在框架、注冊中心以及生態(tài)的成熟度還沒有達到開箱即用的地步,如果是初創(chuàng)公司,首先要確保有人能把控整個系統(tǒng),否則貿(mào)然上微服務(wù)適得其反。
我覺得上微服務(wù)要先回答幾個問題:
為什么要上微服務(wù)?是為了解決當(dāng)前的研發(fā)交付效率問題還是為了方便以后的擴展或者變更?前者的緊迫性大于后者。如果僅僅是后者的話,個人建議等業(yè)務(wù)模式驗證后再進行微服務(wù)拆分,而不是創(chuàng)業(yè)初期就立刻使用微服務(wù)模式。
團隊對新技術(shù)的接納度如何?能否隨著微服務(wù)技術(shù)的演進而跟進。微服務(wù)要伴隨著自動化持續(xù)交付,以及服務(wù)管理和治理工具(主要是解決大量微服務(wù)的管理問題),而當(dāng)前這些系統(tǒng)都在快速演進,需要有精力持續(xù)跟進。
綜合說一下,建議初創(chuàng)團隊謹(jǐn)慎采用微服務(wù),不過可以借鑒思路。比如先從自動化持續(xù)交付做起,然后再上線容器編排,再搞服務(wù)拆分以及治理。
如果以上都搞定的情況下,自己設(shè)計微服務(wù)體系,首先是選擇一個注冊中心 Etcd、Zookeeper、Consul、Eureka 等。個人其實是比較看好 Consul、Ureka 這樣專門的服務(wù)注冊中心,因為現(xiàn)在微服務(wù)最大的一個問題是注冊中心的服務(wù)元數(shù)據(jù)格式?jīng)]有標(biāo)準(zhǔn)。其次選擇一種遠程通訊協(xié)議和框架。拆分自己的業(yè)務(wù)其實是相對簡單的,可以根據(jù)數(shù)據(jù)的隔離以及團隊結(jié)構(gòu)進行拆分。
問:一個創(chuàng)業(yè)公司,項目已經(jīng)上線,怎么進行微服務(wù)切分。
答: 這個可以參考前一個問題,先要思考為什么要切分,不要為微服務(wù)化而微服務(wù)化,然后再思考怎么切分。切分之前可以先進行一些技術(shù)改造,方便切分。
比如避免模塊間直接共享后端存儲,模塊間的互相依賴和調(diào)用至少要上升到 Service 層面,不允許跨 Service 直接調(diào)用 DAO(Data Access Object)。等這些都做完了,拆分就是把 Service 之間的依賴變成遠程模式即可。
基礎(chǔ)運維層面,我覺得如果當(dāng)前沒有太多精力的話,還是可以等一等各云廠商的方案。比如我們現(xiàn)在基于 IaaS 的應(yīng)用調(diào)度方案,還有即將推出的 k8s 服務(wù)。
問:目前每個 service 功能比較多,類似這樣的服務(wù)功能做的比較臃腫。感覺到做不下去了。如果不分,以后每個 service 功能更龐大,據(jù)庫也不方便做分庫方案。
答:這個我覺得是架構(gòu)設(shè)計上的問題,可以不用著急拆成獨立部署的服務(wù),可以先拆成互相依賴的 lib。如果獨立拆分為 lib 都困難,那拆成獨立部署的 Service 更困難。
問:如果拆分,牽扯多庫操作的微服務(wù)之間怎么進行事務(wù)控制,怎么保證事務(wù)一致性。
答:微服務(wù)的拆分可以先做架構(gòu)設(shè)計上的邏輯拆分,再做服務(wù)實體拆分。
大多數(shù)情況下其實不需要跨服務(wù)的事務(wù)。首先,就要思考服務(wù)是否拆的合理。如果真的需要,那可以考慮通過其他的機制實現(xiàn)分布式事務(wù),不過這個復(fù)雜度就會很高。但其實大多數(shù)場景你需要的可能不是分布式事務(wù),只是需要一個分布式鎖而已。
問:需要多表關(guān)聯(lián)查詢的時候怎么處理,及事務(wù)怎么控制?
答:數(shù)據(jù)庫分庫方案和微服務(wù)沒多大關(guān)系。如果當(dāng)前多個模塊之間有數(shù)據(jù)共享的話,建議先消除數(shù)據(jù)共享。
如果拆分成微服務(wù),肯定要消除多表關(guān)聯(lián)查詢,除非多個表屬于同一個服務(wù)。實際上拆分了微服務(wù)后,原來的多表關(guān)聯(lián)查詢需要通過代碼邏輯實現(xiàn)。這樣雖然增加了復(fù)雜度,但好處是可以很好的利用緩存。
問:請問服務(wù)拆分,是數(shù)據(jù)先拆還是架構(gòu)先拆,為什么?
答:你說的數(shù)據(jù)先拆是消除數(shù)據(jù)共享么?建議是先消除數(shù)據(jù)共享再做架構(gòu)拆分。
問:請問 QingCloud 的 IaaS 是完全自主研發(fā)的嗎?為什么沒有使用 OpenStack、CloudStack 一類的?應(yīng)用 Zookeeper Etcd 是實現(xiàn) IaaS 相關(guān)功能嗎?QingCloud IaaS 的微服務(wù)劃分粒度是多少,能否舉個具體例子?
答:青云QingCloud 的 IaaS 平臺是自主研發(fā)。
OpenStack 在公有云多租戶情況下瓶頸較多,并且功能演進不容易掌控。 Etcd、Metad 是指我們給用戶提供的服務(wù)元數(shù)據(jù)服務(wù),和我們的 IaaS 層沒有關(guān)系。
問:請問 QingCloud 使用什么語言及相關(guān)庫或框架開發(fā)?是不是應(yīng)該按業(yè)務(wù)模塊劃分?jǐn)?shù)據(jù)庫?
答:主要使用 Python??蚣苁褂昧?ZeroMQ 等。是按照業(yè)務(wù)模塊劃分?jǐn)?shù)據(jù)庫。
問:看到一種說法,微服務(wù)的架構(gòu)應(yīng)該各自獨立管理自己的數(shù)據(jù)。那么多個微服務(wù)訪問同一個 MySQL,或者其他 NoSQL 服務(wù),是一種錯誤的實踐嗎?原本就有關(guān)聯(lián)的微服務(wù)都訪問同一個數(shù)據(jù)庫,不是比通過 API 互相通訊,效率更高嗎?
答:我同意這種說法,理想情況下每個微服務(wù)后面依賴的基礎(chǔ)設(shè)施服務(wù)都應(yīng)該是獨立的。
但現(xiàn)實情況不可能這么理想,出于成本等各種原因的考慮,需要共享數(shù)據(jù)庫。共享數(shù)據(jù)庫實例一定程度只影響部署和運維的獨立性,這個是可以接受的。但直接共享數(shù)據(jù)則是絕對『邪惡』的,是要避免的,即便不是微服務(wù)。單體應(yīng)用也應(yīng)該避免模塊之間直接共享數(shù)據(jù),而是要通過互相的 Service 依賴。
避免這樣做的主要原因是數(shù)據(jù)本身不能獨立成服務(wù),而是要通過代碼邏輯的『解釋』。如果把數(shù)據(jù)直接共享出去,當(dāng)需要修改數(shù)據(jù)的『解釋』方式,比如修改表結(jié)構(gòu),或者需要讀取的時候?qū)?shù)據(jù)特殊處理一下,或者加一層緩存不立刻刷新到數(shù)據(jù)庫等等,你都不知道牽扯哪些模塊,哪些部門。
所以數(shù)據(jù)最好是通過 API『解釋』后輸出結(jié)果,如果有變更只需要修改一個模塊即可。
問:我想再追問一下。多個微服務(wù)訪問的 MySQL,應(yīng)該是在 DataBase 級隔離,還是大家各自自覺?此處的“隔離”指邏輯意義上的隔離。
答:邏輯意義上肯定是需要隔離的。
問:但是這樣性能上又差了。
答:微服務(wù)本身就不是解決性能問題的,如果要性能,本地的 lib 依賴調(diào)用肯定效率高于遠程的 RPC。
問:比如:某個表邏輯上就是只能由某個服務(wù)去讀寫,其他服務(wù)不能(嚴(yán)格禁止)去直接訪問這些數(shù)據(jù)。只能通過 API。
答:對,我的回答就是這個意思,服務(wù)之間的數(shù)據(jù)通過庫直接共享是要絕對避免的。不然就是一個坑。
問:在性能與架構(gòu)的清晰性上,要有一個折中的點,這個很難把握。
答:其實反過來想一下,如果你的業(yè)務(wù)需要緩存,本身就要避免數(shù)據(jù)庫層面的共享了。所以這個不僅僅是微服務(wù)的要求,一個沒有緩存的服務(wù),還考慮什么性能問題。
問:在我們的項目里,我也做過一個類似 Confd+Metad 的項目,但是沒有推廣成功。所以很想問問,實際推行這個方案時,有沒有遇到什么阻礙?
答:這個我們也才剛開始推廣,內(nèi)部試驗的結(jié)果是:剛開始還是有一些學(xué)習(xí)成本的,但只要有一個經(jīng)驗之后就容易了。
我們這個其實是給基礎(chǔ)設(shè)施服務(wù)的廠商和用戶之間搭建了一個橋梁,讓基礎(chǔ)設(shè)施服務(wù)的交付更簡單,讓用戶使用也更簡單,這兩方面的推廣我感覺應(yīng)該阻礙不大。更大的阻礙應(yīng)該在于讓用戶將自己的服務(wù)進行改造。這一點上我們還有許多需要改進的地方。
問:我解釋一下當(dāng)時的情況,也可以進一步聊聊。我當(dāng)時其實做得特別簡單,基于 Redis,做了一個 Items+Template 的模型,然后寫了一個 Ruby 的腳本,可以一鍵生成各種配置文件。當(dāng)時只花了 2 個小時不到的時間,自己覺得很得意。受到的質(zhì)疑是:為啥自己造輪子?不是有 Ansible or Chef 嗎?基于成熟工具的配置管理,不是更加可靠嗎?
答:我不太清楚你說的阻力來自于哪方面,我們這個服務(wù)對內(nèi)部人來說降低了 PaaS 服務(wù)的研發(fā)成本,大家非常歡迎。
我覺得只針對這點,你的這個輪子就值了。比如你可以讓他們做一下 LB,后端服務(wù)節(jié)點擴展后 LB 配置的自動變更。這點 Ansible 就做不到。
問:對了,我當(dāng)時的那個工具,不是一個常駐服務(wù),只是為了 Docker Build 的時候,生成配置文件用的。所以,價值低了。
答:哦,如果這樣的話,你的這個工具就和 Ansible 差不多了。
問:現(xiàn)在我們會選擇 k8s 的方案,其實反而不必那么麻煩搞配置了。
答:嗯,不過 k8s 中的服務(wù),有時候也是需要變更配置的,現(xiàn)在也沒有比較好的方案。
問:對于中小型企業(yè)來說,很可能都還沒用上 Zookeeper、Docker 這類技術(shù),那么微服務(wù)對于這些企業(yè)來說意義在哪,或者有必要嗎?
答:微服務(wù)其實有兩種場景。
一種是企業(yè)應(yīng)用私有部署的場景。
這種場景下,拆分微服務(wù)對應(yīng)用生產(chǎn)商來說,可以加快交付效率,方便形成產(chǎn)品矩陣,通過各種組合的方式交付產(chǎn)品給用戶。比如一個任務(wù)管理系統(tǒng),可以將用戶系統(tǒng),任務(wù)系統(tǒng),溝通系統(tǒng)拆開,這樣用戶系統(tǒng)和溝通系統(tǒng)可以再組合一個采購管理系統(tǒng),就是一套新的產(chǎn)品了。但這種拆分提高了使用者的安裝運維成本,需要等待分布式應(yīng)用管理系統(tǒng)的普及,比如我們做的這個系統(tǒng)就是一種。
另外一種是互聯(lián)網(wǎng)或者 SaaS 服務(wù)。
這種場景下,運維者就是生產(chǎn)者自己,拆分的意義在于研發(fā)交付效率。如果當(dāng)前這個的瓶頸不在這里,可以不用著急拆分,但思路可以借鑒,從而降低以后拆分時的成本。
Zookeeper、Docker 這種其實應(yīng)該屬于基礎(chǔ)設(shè)施服務(wù),不應(yīng)該是應(yīng)用開發(fā)者本身需要太多關(guān)注的,只是當(dāng)前的微服務(wù)體系還不太成熟。等生態(tài)再成熟一些,開發(fā)者就可以只關(guān)心自己的業(yè)務(wù)邏輯拆分和定義了,其他的都托管到云服務(wù)即可。
問:到底什么是微服務(wù)?能符合自發(fā)布、自部署、松耦合嗎?如果不是,怎么成為微服務(wù)?
答:微服務(wù)的概念各人有各人的解釋,有認(rèn)為微服務(wù)就是無狀態(tài)的,所以數(shù)據(jù)庫本身不能算微服務(wù)。
但無論如何,即便是認(rèn)為基礎(chǔ)設(shè)施服務(wù)不算微服務(wù),微服務(wù)是肯定是需要基礎(chǔ)設(shè)施服務(wù)的,探討這個問題的解決方案至少是有意義的。
另外我個人其實不太同意微服務(wù)(microservice)這個詞的。世上沒有微服務(wù)(microservice),只有服務(wù)(service),但服務(wù)這個詞被 SOA 給用了,Martin Flower 可能覺得不好區(qū)分,所以加了個『微』(micro)字。
在我的理念里,服務(wù)就是一組暴露出遠程編程接口的 Endpoint,接口可以是 Rest,可以是 Rpc,也可以是自定義協(xié)議(比如數(shù)據(jù)庫或者緩存)。
問:正想追問一句,你對 Cloud Native 這個詞,怎么看?
答:Cloud Native 我也算是國內(nèi)早期推廣者之一了。去年青云QingCloud 大會上,我講的就是這個主題。
Cloud Native 我覺得是當(dāng)前云的一種演進,IaaS 的任務(wù)是讓大家先接受云,所以需要適應(yīng)傳統(tǒng)的應(yīng)用機制,網(wǎng)絡(luò)、主機、存儲等都是模擬傳統(tǒng)的機房的機制。
但到現(xiàn)在,大家基本上都接受 IaaS 了,第一步任務(wù)算是完成了,現(xiàn)在需要的是應(yīng)用來適應(yīng)云的機制,所以叫 Cloud Native 。
下面粘貼我的兩頁 PPT 來解答這個問題。


問:那和 PaaS 又什么區(qū)別?
答:傳統(tǒng)的 PaaS 對應(yīng)用的限制太多了,通用性有問題。但其實本質(zhì)上用戶需要的是一種更通用的 PaaS。
問:我覺得基礎(chǔ)設(shè)施已經(jīng)屬于 IaaS 了。
答:其實我的觀點是以后 IaaS 會回歸到硬件層,上面的都歸 PaaS/CaaS 了。
問:青云在比較了業(yè)界現(xiàn)有的產(chǎn)品(Ansible/Puppet/Kubernetes/Mesos)后,在深知現(xiàn)有產(chǎn)品的缺點后,是如何做出自己的 QingCloud 應(yīng)用配置中心的?如何克服現(xiàn)有產(chǎn)品的那些缺點?如何做出自己獨有的優(yōu)勢,以便推向公共應(yīng)用市場時能打敗其他同類競爭產(chǎn)品?
答:這個談不上打敗,各種產(chǎn)品有各種產(chǎn)品的應(yīng)用場景。各種產(chǎn)品其實都是在現(xiàn)實和理想之間的一種折中,只不過看傾向與哪邊了。
比如我們的這個產(chǎn)品,相對 Kubernetes 來說,更偏向于現(xiàn)實,為了適應(yīng)各種集群系統(tǒng),做了許多妥協(xié)。因為 Kubernetes可以等待應(yīng)用去適應(yīng)它,而不是它來適應(yīng)應(yīng)用,我們就不行,我們得交付給用戶一個立刻可用的產(chǎn)品,還要能適應(yīng)當(dāng)前的多數(shù)分布式應(yīng)用。
另外我們這個產(chǎn)品當(dāng)前還是依托于我們的 IaaS,無法獨立使用,所以適用范圍上來說,還是不一樣的。
問:微服務(wù)化,一般都用什么來實現(xiàn)分布式鎖來保證數(shù)據(jù)的最終一致性呢?
答:分布式鎖的實現(xiàn)方式很多,比如用 Zookeeper,Etcd,Redis。本質(zhì)上就是依賴一個共享存儲來實現(xiàn),利用共享存儲的某個排他性操作,比如創(chuàng)建某個 Key,而獲得一個獨占資源的標(biāo)志。
互聯(lián)網(wǎng)業(yè)務(wù)實現(xiàn)最終一致性大多數(shù)不依賴于鎖,而是通過其他的機制,比如定時的核對數(shù)據(jù)等方式來實現(xiàn)。
問:請問 QingCloud 的基礎(chǔ)服務(wù)的運維和自動化框架的研發(fā),是由運維來負責(zé)后期維護么,還是開發(fā)來負責(zé)維護的?在初創(chuàng)公司,有哪些服務(wù),例如(數(shù)據(jù)庫服務(wù)),適合做成微服務(wù),數(shù)據(jù)庫服務(wù)切分的原則是什么?
答:我們還是主要靠研發(fā)來維護具體的服務(wù)。初創(chuàng)公司的無狀態(tài)業(yè)務(wù)服務(wù)適合做成微服務(wù),其他的有狀態(tài)服務(wù)除非是有云平臺提供這種能力,否則不建議自己搞。數(shù)據(jù)庫服務(wù)切分的原則這個貌似也想不出一個通用的原則,主要考慮獨立性,數(shù)據(jù)量等元素吧。
問:微服務(wù)架構(gòu)里各個微服務(wù)的配置管理有最佳實踐么?一個問題是配置很多,一個問題是當(dāng)需要同步修改多個微服務(wù)(不是指一個邏輯服務(wù)的多個實例,而是有上下游調(diào)用關(guān)系的服務(wù)們)如何做到優(yōu)雅的配置更新?
答:依賴服務(wù)配置更新的思路就是通過服務(wù)注冊中心來定義依賴關(guān)系,服務(wù)的變更要通過注冊中心通知到其他的依賴方,然后由依賴方自己變更。
關(guān)于本場 Chat 的更多內(nèi)容請點擊閱讀原文。
- FIN -

|