什麼時候才是微服務拆分的最佳時機?
提到微服務,服務拆分是繞不過去的話題,但是微服務不是說拆就能拆的,需要很多的前提條件。
首先,首先在基礎設施層面,要有一個持續整合的平臺,使得服務在拆分的過程中,功能的一致性,這種一致性不能透過人的經驗來,而需要經過大量的迴歸測試集,並且持續的拆分,持續的演進,持續的整合,從而保證系統時刻處於可以驗證交付的狀態,而非閉門拆分一段時間,最終誰也不知道功能最終究竟有沒有bug,因而需要另外一個月的時間專門修改bug。
其次在接入層,API和UI要動靜分離,API由API閘道器統一的管理,這樣後端無論如何拆分,可以保證對於前端來講,統一的入口,而且可以實現拆分過程中的灰度釋出,路由分發,流量切分,從而保證拆分的平滑進行。而且拆分後的微服務之間,為了高效能,是不建議每次呼叫都進行認證鑑權的,而是在API閘道器上做統一的認證鑑權,一旦進入閘道器,服務之間的呼叫就是可信的。
其三對於資料庫,需要進行良好的設計,不應該有大量的聯合查詢,而是將資料庫當成一個簡單的key-value查詢,複雜的聯合查詢透過應用層,或者透過Elasticsearch進行。如果資料庫表之間耦合的非常嚴重,其實服務拆分是拆不出來的。
其四要做應用的無狀態化,只有無狀態的應用,才能橫向擴充套件,這樣拆分才有意義。
那麼, 滿足了服務拆分的基礎設施前提之後,我們應該先拆哪個模組,後拆哪個模組呢?在什麼情況下一個模組應該拆分出來呢?
切記,微服務拆分絕非一個大躍進運動,由高層發起,把一個應用拆分的七零八落的,最終大大增加運維成本,但是並不會帶來收益。
滿足上述基本條件後,我們還要看業務變化,才能找到拆分的最佳時機。
第一,有快速迭代的需求。
網際網路產品的特點就是迭代速度快,一般一年半就能決出勝負,第一一統天下,第二被第一收購,其他死翹翹。所以快速上線,快速迭代,就是生命線,而且一旦成功就是百億身家,所以無論付出多大運維成本,使用微服務架構都是值得的。
這也就是為什麼大部分使用微服務架構的都是網際網路企業,因為對於這些企業來講收益明顯。而對於很多傳統的應用,半年更新一次,企業運營相對平穩,IT系統的好壞對於業務沒有關鍵性影響,在他們眼中,微服務化改造帶來的效果,還不如開發多加幾次班。
第二,提交程式碼頻繁出現大量衝突
微服務對於快速迭代的效果,首先是開發獨立,如果是一單體應用,幾百人開發一個模組,如果使用GIT做程式碼管理,則經常會遇到的事情就是程式碼提交衝突。
同樣一個模組,你也改,他也改,幾百人根本沒辦法溝通。所以當你想提交一個程式碼的時候,發現和別人提交的衝突了,於是因為你是後提交的人,你有責任去merge程式碼,好不容易merge成功了,等再次提交的時候,發現又衝突了,你是不是很惱火。隨著團隊規模越大,衝突機率越大。
所以應該拆分成不同的模組,每十個人左右維護一個模組,也即一個工程,首先程式碼衝突的機率小多了,而且有了衝突,一個小組一吼,基本上問題就解決了。
每個模組對外提供介面,其他依賴模組可以不用關注具體的實現細節,只需要保證介面正確就可以。
第三,小功能要積累到大版本才能上線,上線開總監級別大會
微服務對於快速迭代的效果,首先是上線獨立。如果沒有拆分微服務,每次上線都是一件很痛苦的事情。當你修改了一個邊角的小功能,但是你不敢馬上上線,因為你依賴的其他模組才開發了一半,你要等他,等他好了,也不敢馬上上線,因為另一個被依賴的模組也開發了一半,當所有的模組都耦合在一起,互相依賴,誰也沒辦法獨立上線,而是需要總監協調各個團隊,大家開大會,約定一個時間點,無論大小功能,死活都要這天上線。
這種模式導致上線的時候,單次上線的需求列表非常長,這樣風險比較大,可能小功能的錯誤會導致大功能的上線不正常,將如此長的功能,需要一點點check,非常小心,這樣上線時間長,影響範圍大。因而這種的迭代速度快不了,頂多一個月一次就不錯了。
服務拆分後,在介面穩定的情況下,不同的模組可以獨立上線。這樣上線的次數增多,單次上線的需求列表變小,可以隨時回滾,風險變小,時間變短,影響面小,從而迭代速度加快。
對於介面要升級部分,保證灰度,先做介面新增,而非原介面變更,當註冊中心中監控到的呼叫情況,發現介面已經不用了,再刪除。
微服務解決的問題還有高併發。網際網路一個產品的特點就是在短期內要積累大量的使用者,這甚至比營收和利潤還重要,如果沒有大量的使用者基數,融資都會有問題。
因而對於併發量不大的系統,進行微服務化的驅動力差一些,如果只有不多的使用者線上,多執行緒就能解決問題,最多做好無狀態化,前面部署個負載均衡,單體應用部署多份。
第四,橫向擴充套件流程複雜,主要業務和次要業務耦合
單體應用無狀態化之後,雖然透過部署多份,可以承載一定的併發量,但是資源非常浪費。因為有的業務是需要擴容的,例如下單和支付,有的業務是不需要擴容的,例如註冊。如果一起擴容,消耗的資源可能是拆分後的幾倍,成本可能多出幾個億。而且由於配置複雜,在同一個工程裡面,往往在配置檔案中是這樣組織的,這一塊是這個模組的,下一塊是另一個模組的,這樣擴容的時候,一些邊角的業務,也是需要對配置進行詳細稽核,否則不敢貿然擴容。
第五,熔斷降級全靠if-else
在高併發場景下,我們希望一個請求如果不成功,不要佔用資源,應該儘快失敗,儘快返回,而且希望當一些邊角的業務不正常的情況下,主要業務流程不受影響。這就需要熔斷策略,也即當A呼叫B,而B總是不正常的時候,為了讓B不要波及到A,可以對B的呼叫進行熔斷,也即A不呼叫B,而是返回暫時的fallback資料,當B正常的時候,再放開熔斷,進行正常的呼叫。
有時候為了保證核心業務流程,邊角的業務流程,如評論,庫存數目等,人工設定為降級的狀態,也即預設不呼叫,將所有的資源用於大促的下單和支付流程。
如果核心業務流程和邊角業務流程在同一個程式中,就需要使用大量的if-else語句,根據下發的配置來判斷是否熔斷或者降級,這會使得配置異常複雜,難以維護。
如果核心業務和邊角業務分成兩個程式,就可以使用標準的熔斷降級策略,配置在某種情況下,放棄對另一個程式的呼叫,可以進行統一的維護。
總之,微服務拆分的過程,應該是一個由痛點驅動的,是業務真正遇到了快速迭代和高併發的問題。如果不拆分,將對於業務的發展帶來影響,只有這個時候,微服務的拆分才有確定收益,增加的運維成本才值得。
(本文作者為:網易雲首席架構師 劉超)
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31547898/viewspace-2214182/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 什麼時候你不應該使用微服務微服務
- 什麼時候才是最佳就業季?其實選對風口很重要!就業
- 微服務的戰爭:按什麼維度拆分服務微服務
- C++中什麼時候用move,什麼時候用forward?C++Forward
- 什麼時候釋出
- 什麼時候呼叫layoutSubviewsView
- 機器什麼時候能夠學習?
- 微服務拆分到什麼粒度合適——康威定律微服務
- session是什麼時候建立的Session
- 什麼時候採用socket通訊,什麼時候採用http通訊HTTP
- 新版什麼時候釋出?
- 什麼時候該用vuex?Vue
- 到底什麼時候使用mqMQ
- 什麼時候該用MongoDB?MongoDB
- EJB2.0中什麼時候用local interface,什麼時候用remote interface (轉)REM
- Python的類什麼時候用Python
- win11什麼時候釋出的 win11什麼時候推送詳細介紹
- request.getParameter("name")什麼時候獲取的引數是null,什麼時候為""空字串Null字串
- 我們什麼時候才能信賴機器人機器人
- Haskell程式設計精華:什麼時候該註釋,什麼時候不該註釋Haskell程式設計
- Unity ECS System在什麼時候更新?如何自定義這個更新的時機?Unity
- beego 什麼時候支援grpcGoRPC
- python什麼時候縮排Python
- Mybatis什麼時候需要宣告jdbcType?MyBatisJDBC
- 什麼時候使用z-index?Index
- 什麼時候使用 Lambda 函式?函式
- 什麼時候Linux才能完美?Linux
- 什麼時候Haskell快於CHaskell
- 何時入場才是好時機
- 什麼時候用有狀態session bean,什麼時候用無狀態session bean (轉)SessionBean
- session的狀態什麼時候是snipedSession
- MySQL什麼時候會使用內部臨時表?MySql
- 舉例說明你什麼時候會用抽象類,什麼時候更願意使用介面?抽象
- 到底什麼樣的 REST 才是最佳 REST?REST
- 什麼時候 AngularJS 會超越 jQueryAngularJSjQuery
- 屬性提示什麼時候不出現
- oracle commit的時候究竟發生了什麼OracleMIT
- Android 7.0什麼時候推出?安卓7.0各機型推送更新時間預測Android安卓