之前講解了什麼是微服務:微服務的核心在於服務治理,微服務架構是將複雜臃腫的單體應用進行細粒度的服務化拆分,每個拆分出來的服務各自獨立打包部署,並交由小團隊進行開發和運維,從而極大地提高了應用交付的效率。 什麼時候進行服務化拆分?拆分單體應用有哪些標準呢? 什麼時候進行服務化拆分? 比如做社交 App ...
之前講解了什麼是微服務:微服務的核心在於服務治理,微服務架構是將複雜臃腫的單體應用進行細粒度的服務化拆分,每個拆分出來的服務各自獨立打包部署,並交由小團隊進行開發和運維,從而極大地提高了應用交付的效率。
什麼時候進行服務化拆分?拆分單體應用有哪些標準呢?
什麼時候進行服務化拆分?
比如做社交 App,初期為了快速上線,驗證可行性,可以只開發首頁信息流、評論等基本功能。產品上線後,經過一段時間的運營,用戶開始逐步增多,可行性驗證通過,下一階段就需要進一步增加更多的新特性來吸引更多的目標用戶,比如再給這個社交 App 添加個人主頁顯示、消息通知等功能。
這個時候就需要大規模地擴張開發人員,以支撐多個功能的開發。如果這個時候繼續採用單體應用架構,多個功能模塊混雜在一起開發、測試和部署的話,就會導致不同功能之間相互影響,一次打包部署需要所有的功能都測試 OK 才能上線。而且,多個功能模塊混部在一起,對線上服務的穩定性也是個巨大的挑戰。
再例舉一個 58 到家的例子,隨著業務越來越複雜,數據量越來越大,併發量越來越大,15 年的時候,58 到家的架構碰到了種種問題:
- 垂直業務擴展,家政、麗人、速運、平臺,一些相似的業務代碼拷貝越來越嚴重
- 數據量、併發量提升,底層架構複雜性不斷向上游擴散,所有調用方都需要關註緩存、分庫、存儲引擎等,效率逐步降低
- jar 包耦合,多個系統依賴一個公用的 jar 包,一個業務升級導致相容性問題,影響其他業務
- 資料庫耦合,多個業務公用一個資料庫,相互耦合,相互影響
- SQL 質量低,業務相互耦合,一個業務編寫了一個低質量的 SQL,導致其他業務受影響
這個時候 58 到家開始進行服務化拆分,找到通用痛點,抽象出通用數據訪問與子業務,然後將它們下沉成微服務。
一般來說,一旦單體應用同時進行開發的人員超過 10 人,就會遇到上面的問題,這個時候就該考慮進行服務化拆分了。
服務化拆分的兩種姿勢
那麼服務化拆分具體該如何實施呢?一個最有效的手段就是將不同的功能模塊服務化,獨立部署和運維。以前面提到的社交 App 為例,可以認為首頁信息流是一個服務,評論是一個服務,消息通知是一個服務,個人主頁也是一個服務。
這種服務化拆分方式是縱向拆分,是從業務維度進行拆分。標準是按照業務的關聯程度來決定,關聯比較密切的業務適合拆分為一個微服務,而功能相對比較獨立的業務適合單獨拆分為一個微服務。
還有一種服務化拆分方式是橫向拆分,是從公共且獨立功能維度拆分。標準是按照是否有公共的被多個其他服務調用,且依賴的資源獨立不與其他業務耦合。
以前面的社交 App 為例,無論是首頁信息流、評論、消息箱還是個人主頁,都需要顯示用戶的昵稱。如果把用戶的昵稱功能單獨部署成一個獨立的服務,那麼有什麼變更我只需要上線這個服務即可,其他服務不受影響,開發和上線成本就大大降低了。
服務化拆分的前置條件
一般情況下,業務系統引入新技術就必然會帶來架構的複雜度提升,在具體決策前,先要認識到新架構會帶來哪些新的問題,這些問題你和你的團隊是否能夠解決?如何解決?是自己投入人力建設,還是採用業界開源方案?
下麵幾個問題,是從單體應用遷移到微服務架構時必將面臨也必須解決的。
服務如何定義:對於單體應用來說,不同功能模塊之前相互交互時,通常是以類庫的方式來提供各個模塊的功能。對於微服務來說,每個服務都運行在各自的進程之中,通過介面向外界傳達信息。無論採用哪種通訊協議,是 HTTP 還是 RPC,服務之間的調用都通過介面描述來約定,約定內容包括介面名、介面參數以及介面返回值。
服務如何發佈和訂閱:單體應用由於部署在同一個 WAR 包里,介面之間的調用屬於進程內的調用。而拆分為微服務獨立部署後,就需要一個能夠記錄每個服務提供者的地址以供服務調用者查詢,也就是註冊中心(如 Zookeeper、Eureka、Consul 等)。
服務如何監控:對於一個服務,需要一種通用的監控方案,能夠覆蓋業務埋點、數據收集、數據處理,最後到數據展示的全鏈路功能。
服務如何治理:拆分為微服務後,服務的數量變多,依賴關係變複雜。比如一個服務的性能有問題時,依賴的服務也會受影響。可以設定一個調用性能閾值,如果一段時間內一直超過閾值,那麼依賴服務的調用可以直接返回,也就是熔斷。
故障如何定位:拆分為微服務後,一次用戶調用可能依賴多個服務,每個服務又部署在不同的節點上,如果用戶調用出現問題,需要一種解決方案能夠將一次用戶請求進行標記,併在多個依賴的服務系統中繼續傳遞,以便串聯所有路徑,從而進行故障定位。
針對上述問題,必須有可行的解決方案之後,才能進行服務化拆分。
總結
無論是縱向拆分還是橫向拆分,都是將單體應用龐雜的功能進行拆分,抽離成單獨的服務部署。
但並不是功能拆分的越細越好,過度的拆分反而會讓服務數量膨脹變得難以管理,因此找到符合自己業務現狀和團隊人員技術水平的拆分粒度才是可取的。
參考