什麼時候才是微服務拆分的最佳時機?

danny_2018發表於2018-09-14

提到微服務,服務拆分是繞不過去的話題,但是微服務不是說拆就能拆的,需要很多的前提條件。

首先,首先在基礎設施層面,要有一個持續整合的平臺,使得服務在拆分的過程中,功能的一致性,這種一致性不能透過人的經驗來,而需要經過大量的迴歸測試集,並且持續的拆分,持續的演進,持續的整合,從而保證系統時刻處於可以驗證交付的狀態,而非閉門拆分一段時間,最終誰也不知道功能最終究竟有沒有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/,如需轉載,請註明出處,否則將追究法律責任。

相關文章