王淵命:QingCloud微服務實踐全解析
2017年1月16日周二晚8點30分,青云QingCloud 容器平臺負責人王淵命帶來了主題為“基礎設施服務的微服務化”的交流。以下是主持人小媛子整理的問題精華,記錄了老王和讀者間問答的精彩片段。
問:能說說創業小公司在微服務架構設計中的經驗嗎?在保證有限人力和敏捷開發的前提下,怎么設計一套自己的微服務體系?
答:說實話,微服務現在框架以及注冊中心以及生態的成熟度還沒有達到開箱即用的地步,如果是初創公司,首先要確保有人能把控整個系統,否則貿然上微服務適得其反。
我覺得上微服務要先回答幾個問題:
為什么要上微服務?是為了解決當前的研發交付效率問題還是為了方便以后的擴展或者變更?前者的緊迫性大于后者。如果僅僅是后者的話,個人建議等業務模式驗證后再進行微服務拆分,而不是創業初期就立刻使用微服務模式。
團隊對新技術的接納度如何?能否隨著微服務技術的演進而跟進。微服務要伴隨著自動化持續交付,以及服務管理和治理工具(主要是解決大量微服務的管理問題),而當前這些系統都在快速演進,需要有精力持續跟進。
綜合說一下,建議初創團隊謹慎采用微服務,不過可以借鑒思路。比如先從自動化持續交付做起,然后再上線容器編排,再搞服務拆分以及治理。
如果以上都搞定的情況下,自己設計微服務體系,首先是選擇一個注冊中心 etcd, zookeeper, consul, eureka 等。個人其實是比較看好 consul, eureka 這樣專門的服務注冊中心的,因為現在微服務最大的一個問題是注冊中心的服務元數據格式沒有標準。其次選擇一種遠程通訊協議和框架。拆分自己的業務其實是相對簡單的,可以根據數據的隔離以及團隊結構進行拆分。
問:1)一個創業公司,項目已經上線,怎么進行微服務切分?2)目前我的每個service功能比較多,類似這樣的服務功能做的比較臃腫。感覺到做不下去了。如果不分,以后每個service功能更龐大。3)如果不拆的話,數據庫不方便做分庫方案。如果拆分了,那么牽扯多庫操作微服務之間怎么進行事務控制。如果拆分了,那么牽扯多庫操作微服務之間怎么保證事務一致性。
答: 1)這個可以參考前一個問題,先要思考為什么要切分,不要為微服務化而微服務化,然后再思考怎么切分。切分之前可以先進行一些技術改造,方便切分。比如避免模塊間直接共享后端存儲,模塊間的互相依賴和調用至少要上升到service層面,不允許跨service直調用dao。等這些都做完了,拆分就是把service之間的依賴變成遠程模式即可。
基礎運維層面,我覺得如果當前沒有太多精力的話,還是可以等一等各云廠商的方案。比如我們的現在基于IaaS的應用調度方案,還有即將推出的k8s服務。
2)這個我覺得是架構設計上的問題,可以不用著急拆成獨立部署的服務,可以先拆成互相依賴的lib。如果獨立拆分為lib都困難,那拆成獨立部署的service更困難。
3)微服務的拆分可以先做架構設計上的邏輯拆分,再做服務實體拆分。
大多數情況下其實不需要跨服務的事務的,如果需要,就要思考服務是否拆的合理。如果是真需要,那可以考慮通過其他的機制實現分布式事務,不過這個復雜度就會高些了。但其實大多數場景你需要的可能不是分布式事務,只是需要一個分布式鎖而已。
問:需要多表關聯查詢的時候怎么處理,及事務怎么控制?
答:數據庫分庫方案和微服務沒多大關系。如果當前多個模塊之間有數據共享的話,建議先消除數據共享。
如果拆分成微服務,肯定要消除多表關聯查詢的,除非多個表屬于同一個服務。實際上拆分了微服務后,原來的多表關聯查詢是需要通過代碼邏輯實現的。這樣雖然增加了復雜度,但好處是可以很好的利用緩存。
問:請問服務拆分,是數據先拆還是架構先拆,為什么?
答:你說的數據先拆是消除數據共享么?建議是先消除數據共享再做架構拆分。
問:請問QingCloud的IaaS是完全自主研發的嗎?為什么沒有使用openstack cloudstack一類的? 應用zookeeper etcd的層 是實現的IaaS相關功能嗎? QingCloud IaaS的微服務劃分粒度是多少,能否舉個具體例子?
答:是自主研發。openstack在公有云多租戶情況下瓶頸較多,并且功能演進不容易掌控。文章里說的etcd、metad是指我們給用戶提供的服務元數據服務,和我們的IaaS層沒有關系。
問:請問QingCloud使用什么語言及相關庫或框架開發?是不是應該按業務模塊劃分數據庫?
答:主要使用python。框架使用了zeromq等。是的。
問:看到一種說法,微服務的架構應該各自獨立的管理自己的數據。那么多個微服務訪問同一個MySQL,或者其他NoSQL服務,是一種錯誤的實踐嗎?原本就有關聯的微服務都訪問同一個數據庫,不是比通過API互相通訊,效率更高嗎?
答:我同意這種說法,理想情況下每個微服務后面依賴的基礎設施服務都應該是獨立的。
但現實情況不可能這么理想,出于成本等各種原因需要共享數據庫。共享數據庫實例一定程度只影響部署和運維的獨立性,這個是可以接受的。但直接共享數據則是絕對『***』的,是要避免的,即便不是微服務,是單體應用,也應該避免模塊之間直接共享數據,而是要通過互相的service依賴。
避免這樣做的主要原因是數據本身不能獨立成服務,而是要通過代碼邏輯的『解釋』。如果把數據直接共享出去,當需要修改數據的『解釋』方式,比如修改表結構,或者需要讀取的時候對數據特殊處理一下,或者加一層緩存不立刻刷新到數據庫,等等,你都不知道牽扯哪些模塊,哪些部門。
所以數據最好是通過API『解釋』后輸出結果,如果有變更只需要修改一個模塊即可。
問:我想再追問一下。多個微服務,訪問的MySQL,應該是在database級隔離,還是大家各自自覺?此處的“隔離”指邏輯意義上的隔離。
答:邏輯意義上肯定是需要隔離的。
問:但是這樣性能上又差了。
答:微服務本身就不是解決性能問題的,如果要性能,本地的lib依賴調用肯定效率高于遠程的rpc。
問:比如:某個表,邏輯上,就是只能由某個服務去讀寫,其他服務不能(嚴格禁止)去直接訪問這些數據。只能通過API。
答:對,我的回答就是這個意思,服務之間的數據通過庫直接共享是要絕對避免的。不然就是一個坑。
問:是啊,這就是困擾的問題。在性能與架構的清晰性上,要有一個折中的點,這個很難把握。
答:其實反過來想一下,如果你的業務需要緩存,本身就要避免數據庫層面的共享了。所以這個不僅僅是微服務的要求。一個沒有緩存的服務,還考慮什么性能問題。
問:在我們的項目里,我也做過一個類似confd+metad的項目,但是沒有推廣成功。所以很想問問,實際推行這個方案時,有沒有遇到什么阻礙?
答:這個我們也才剛開始推廣,內部試驗的結果是,剛開始還是有一些學習成本的,但只要有一個經驗之后就容易了。
我們這個其實是給基礎設施服務的廠商和用戶之間搭建了一個橋梁,讓基礎設施服務的交付更簡單,讓用戶使用也更簡單,這兩方面的推廣我感覺應該阻礙不大。更大的阻礙應該在于讓用戶將自己的服務進行改造。這一點上我們還有許多需要改進的地方。
問:我解釋一下當時的情況,也可以進一步聊聊。我當時其實做得特別簡單,基于redis,做了一個items+template的模型,然后寫了一個ruby的腳本,可以一鍵生成各種配置文件。當時只花了2個小時不到的時間,自己覺得很得意。受到的質疑是:為啥自己造輪子?不是有ansible or chef嗎?基于成熟工具的配置管理,不是更加可靠嗎?
答:我不太清楚你說的阻力來自于哪方面,我們這個對內部人來說降低了PaaS服務的研發成本,肯定是歡迎的。
我覺得只針對這點,你的這個輪子就值了。比如你可以讓他們做一下lb后端服務節點擴展后lb配置的自動變更。這點 ansible就做不到。
問:對了,我當時的那個工具,不是一個常駐服務,只是為了docker build的時候,生成配置文件用的。所以,價值低了。
答:哦,如果這樣的話,你的這個工具就和ansible差不多了。
問:不過,現在我們會選擇k8s的方案,其實反而不必那么麻煩搞配置了。
答:嗯,不過k8s中的服務,有時候也是需要變更配置的,現在也沒有比較好的方案。
問:對于中小型企業來說,很可能都還沒用上zookeeper、docker這類技術,那么微服務對于這些企業來說意義在哪,或者有必要嗎?
答:微服務其實有兩種場景。
一種是企業應用私有部署的場景。
這種場景下,拆分微服務,對應用生產商來說,可以加快交付效率,方便形成產品矩陣,通過各種組合的方式交付產品給用戶。比如一個任務管理系統,可以將用戶系統,任務系統,溝通系統拆開,這樣用戶系統和溝通系統可以再組合一個采購管理系統,就是一套新的產品了。但這種拆分提高了使用者的安裝運維成本,需要等待分布式應用管理系統的普及,比如我們做的這個系統就是一種。
另外一種是互聯網或者SaaS服務。
這種場景下,運維者就是生產者自己,拆分的意義在于研發交付效率。如果當前這個的瓶頸不在這里,可以不用著急拆分,但思路可以借鑒,從而降低以后拆分時的成本。
zookeeper、docker這種其實應該屬于基礎設施服務,不應該是應用開發者本身需要太多關注的,只是當前的微服務體系還不太成熟。等生態再成熟一些,開發者就可以只關心自己的業務邏輯拆分和定義了,其他的都托管到云服務即可。
問:我閱讀了全文,最后我都模糊了微服務的概念了,文章中做的這個叫配置下發吧?不是叫微服務吧?能符合自發布、自部署、松耦合嗎?如果不是,怎么成為微服務?
答:這篇文章探討的問題是微服務的場景下,每個微服務后面的基礎設施服務,如何自動部署?伸縮,如何和應用本身的微服務互相感知?
你可以說這個不叫微服務,畢竟微服務的概念各人有各人的解釋,有認為微服務就是無狀態的,所以數據庫本身不能算微服務。
但無論如何,即便是認為基礎設施服務不算微服務,微服務是肯定是需要基礎設施服務的,探討這個問題的解決方案至少是有意義的。
另外我個人其實不太同意微服務(microservice)這個詞的。世上沒有微服務(microservice),只有服務(service),但服務這個詞被SOA給用了,Martin Flower 可能覺得不好區分,所以加了個『微』(micro)字。
在我的理念里,服務就是一組暴露出遠程編程接口的endpoint,接口可以是 Rest,可以是rpc,也可以是自定義協議(比如數據庫或者緩存)。
問:正想追問一句,你對Cloud Native這個詞,怎么看?
答:Cloud Native 我也算是國內早期推廣者之一了。去年那次青云的開發大會上,我講的就是這個主題。
Cloud Native 我覺得是當前云的一種演進,IaaS的任務是讓大家先接受云,所以需要適應傳統的應用機制,網絡,主機,存儲等都是模擬傳統的機房的機制。
但到現在之后,大家基本上都接受了 IaaS了,第一步任務算是完成了,現在需要的是應用來適應云的機制,所以叫 Cloud Native 。
下面粘貼我的兩頁ppt來解答這個問題。
問:那和PaaS又什么區別?
答:傳統的PaaS對應用的限制太多了,通用性有問題。但其實本質上用戶需要的是一種更通用的 PaaS。
問:我覺得基礎設施已經屬于IaaS了。
答:其實我的觀點是以后 IaaS 會回歸到硬件層,上面的都歸 PaaS/CaaS 了。
問:青云在比較了業界現有的產品(ansible/puppet/kubernetes/mesos)后,在深知現有產品的缺點后,是如何做出自己的 QingCloud 應用配置中心的?如何克服現有產品的那些缺點?如何做出自己獨有的優勢,以便推向公共應用市場時能打敗其他同類競爭產品?想聽更多技術內幕/細節 ;-)
答:這個談不上打敗,各種產品有各種產品的應用場景。各種產品其實都是在現實和理想之間的一種折中,只不過看傾向與哪邊了。
比如我們的這個產品,相對kubernetes來說,更偏向于現實,為了適應各種集群系統,做了許多妥協。因為kubernetes可以等待應用去適應它,而不是它來適應應用,我們就不行,我們得交付給用戶一個立刻可用的產品,還要能適應當前的多數分布式應用。
另外我們這個產品當前還是依托于我們的IaaS,無法獨立使用,所以適用范圍上來說,還是不一樣的。
問:微服務化,一般都用什么來實現分布式鎖來保證數據的最終一致性呢?
答:分布式鎖的實現方式很多,比如用zookeeper,etcd,redis。本質上就是依賴一個共享存儲來實現,利用共享存儲的某個排他性操作,比如創建某個key,而獲得一個獨占資源的標志。
互聯網業務實現最終一致性大多數不依賴于鎖,而是通過其他的機制,比如定時的核對數據等方式來實現。
問:請問QingCloud的基礎服務的運維和自動化框架的研發,是由運維來負責后期維護么,還是開發來負責維護的?在初創公司,有哪些服務,例如(數據庫服務),適合做成微服務,數據庫服務切分的原則是什么?
答:我們還是主要靠研發來維護具體的服務。初創公司的無狀態業務服務適合做成微服務,其他的有狀態服務除非是有云平臺提供這種能力,否則不建議自己搞。數據庫服務切分的原則這個貌似也想不出一個通用的原則,主要考慮獨立性,數據量等元素吧。
問:微服務架構里各個微服務的配置管理有最佳實踐么?一個問題是配置很多,一個問題是當需要同步修改多個微服務(不是指一個邏輯服務的多個實例,而是有上下游調用關系的服務們)如何做到優雅的配置更新?
答:依賴服務配置更新的例子我文章中有,思路就是通過服務注冊中心來定義依賴關系,服務的變更要通過注冊中心通知到其他的依賴方,然后由依賴方自己變更。
(以上內容轉自GitChat,版權歸GitChat所有,轉載請聯系GitChat,微信號:GitChat,原文:《王淵命:QingCloud微服務實踐全解析》
本文轉載自異步社區。
微服務 數據庫
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。