大火的‘微服務架構’詳解與實踐

一、業務背景

1.1 產品現狀

1、各產品系統獨立開發,代碼複用率低,系統之間互相調用,耦合嚴重,系統解耦獨立部署困難。
2、傳統的單體架構,規模越來越大也越來越笨重;當新功能的開發、功能的重構變得不再敏捷可控;測試者的迴歸測試邊界難以琢磨;系統的上線部署也變的艱難
3、高併發訪問下無法提供可靠性服務
4、持續集成、持續部署、持續交付等工程效率化工具嚴重缺失
5、監控系統、日誌分析等系統穩定性工具嚴重缺失
以上種種情況,都讓我們應對需求的變化而變得遲鈍。

大火的‘微服務架構’詳解與實踐

1.2 業務需求

架構肯定是為業務需求而生的,先來看看我們面對的業務需求及其特點。平臺最主要滿足兩大類業務需求:面向餐飲企業在餐飲新零售下的經營和運營需求和麵向產品及運營團隊。
具體來看:
1、餐飲新零售下的餐飲企業經營和運營的痛點

  • 如何提升營銷能力和管理會員,以更低的成本為餐飲企業帶來更多利潤
  • 如何對數據進行深度挖掘和分析,助力決策者進行運營決策
  • 如何掌握實時數據,讓決策者及時瞭解餐廳運營情況

2、面向產品及運營團隊

  • 主要是提升產品控制能力,促進整體系統的良好運轉

因此開發SAAS服務的產品迫在眉睫,需要滿足快速開發、靈活升級、高性能、高可用、高穩定、簡化運維等更高的需求。

大火的‘微服務架構’詳解與實踐

這一步的轉型,不是"快"與"慢",而是"生"與"死"。

二、微服務概念

專注於單一責任與功能獨立運行的服務,模組化方式組合出大型應用。

大火的‘微服務架構’詳解與實踐

2.1 特點

  • 集中式架構:單體無分散
  • 分佈式架構:分散壓力
  • 微服務架構:分散能力
大火的‘微服務架構’詳解與實踐

2.2 微服務架構優勢

  • 每個微服務組件都是簡單靈活的,能夠獨立部署。不再像單體應用時代,應用需要一個龐大的應用服務器來支撐。
  • 可以由一個小團隊負責更專注專業,相應的也就更高效可靠。
  • 微服務之間是松耦合的,微服務內部是高內聚的,每個微服務很容易按需擴展。

三、微服務技術選型和微服務的問題

3.1 技術選型

大火的‘微服務架構’詳解與實踐

3.1.1 技術矩陣結論

  • Netflix提供了比較全面的解決方案
  • Spring Cloud對於Netflix的封裝比較全面
  • Spring Cloud基於Spring Boot,團隊有基礎
  • Spring Cloud提供了Control Bus能夠幫助實現監控埋點
  • 業務應用部署在阿里雲,Spring Cloud對12 Factors以及Cloud-Native的支持,有利於在雲環境下使用

3.1.2 團隊期望

  • 首先支持Rest
  • 團隊技術棧和實例比較單薄,希望對新的技術平滑的學習曲線和能夠Hold住
  • 小團隊,希望能夠有一個比較全面的解決方案
  • 目前團隊主要採用Spring Cloud + Spring Boot的方式實現服務化

有關技術選型詳細分析,請查看我的上一篇文章《我的技術選型》。

3.2 微服務帶來的問題

大火的‘微服務架構’詳解與實踐

  • 依賴服務變更很難跟蹤,其他團隊的服務接口文檔過期怎麼辦?依賴的服務沒有準備好,如何驗證我開發的功能。
  • 部分模塊重複構建,跨團隊、跨系統、跨語言會有很多的重複建設。
  • 微服務放大了分佈式架構的系列問題,如分佈式事務怎麼處理?依賴服務不穩定怎麼辦?
  • 運維複雜度陡增,如:部署物數量多、監控進程多導致整體運維複雜度提升。
大火的‘微服務架構’詳解與實踐

上面這些問題我們應該都遇到過,並且總結形成了自己的一些解決方案,比如提供文檔管理、服務治理、服務模擬的工具和框架; 實現統一認證、統一配置、統一日誌框架、分佈式彙總分析; 採用全局事務方案、採用異步模擬同步;搭建持續集成平臺、統一監控平臺等等。

微服務架構是一把雙刃劍,雖然解決了集中式架構和分佈式架構的問題,卻帶來了如上種種問題。因此我們是需要一個微服務應用平臺才能整體性的解決這些問題。

四、微服務架構設計

4.1 微服務應用架構設計原則

大火的‘微服務架構’詳解與實踐

4.2 微服務應用架構設計目標

微服務架構設計的目標,滿足快速開發、靈活升級、高性能、高可用、高穩定、簡化運維等更高的需求。

大火的‘微服務架構’詳解與實踐

4.3 微服務應用總體架構

大火的‘微服務架構’詳解與實踐

微服務應用平臺的總體架構,主要是從開發集成、微服務運行容器與平臺、運行時監控治理和外部渠道接入等維度來劃分和考慮的。

  • 開發集成:主要是搭建一個微服務平臺需要具備的一些工具和倉庫
  • 運行時:要有微服務平臺來提供一些基礎能力和分佈式的支撐能力,我們的微服務運行容器則會運行在這個平臺之上。
  • 監控治理:則是致力於在運行時能夠對受管的微服務進行統一的監控、配置等能力。
  • 服務網關: 則是負責與前端的WEB應用 移動APP 等渠道集成,對前端請求進行認證鑑權,然後路由轉發。

4.4 微服務框架概覽

大火的‘微服務架構’詳解與實踐

這裡不詳細講解服務框架中每一個組件,另開一篇文章來講解。

五、微服務架構設計落地

5.1 基礎環境

大火的‘微服務架構’詳解與實踐

一個企業的IT建設非常重要的三大基礎環境:團隊協作環境、服務基礎環境、IT基礎設施。

  • 團隊協作環境:主要是DevOps領域的範疇,負責從需求到計劃任務,團隊協作,再到質量管理、持續集成和發佈。
  • 服務基礎環境:指的是微服務應用平臺,其目標主要就是要支撐微服務應用的設計開發測試,運行期的業務數據處理和應用的管理監控。
  • IT基礎設施:主要是各種運行環境支撐如IaaS (VM虛擬化)和CaaS (容器虛擬化)等實現方式。

5.2 服務通信

大火的‘微服務架構’詳解與實踐

服務間的通信,往往採用HTTP+REST 和 RPC通信協議。

HTTP+REST,對服務約束完全靠提供者的自覺。

  • 特點是簡單,對開發使用友好。
  • 缺點治理起來困難,連接的無狀態,缺失多路複用、服務端推送等。

RPC對通信雙方定義了數據約束。

  • 連接大多基於長連接以獲得性能的提升及附帶的服務端推、調用鏈路監控埋點等,增強了系統的附加能力。
  • 缺點是對調用端提出了新的要求。

綜合來看,RPC從性能、契約優先來說具有優勢,如何做到揚長避短呢?
引入GateWay層,讓REST與RPC的優點進行融合,在GateWay層提供REST的接入能力。

5.3 服務註冊/發現

大火的‘微服務架構’詳解與實踐

以前的單體應用之間互相調用時配置個IP或域名就行了,但在微服務架構下,服務提供者會有很多,手工配置IP地址或域名又變成了一個耦合和繁瑣的事情。那麼服務自動註冊發現的方案就解決了這個問題。
我們的服務註冊發現能力是依賴SpringCloud Eureka組件實現的。服務在啟動的時候,會將自己要發佈的服務註冊到服務註冊中心;運行時,如果需要調用其他微服務的接口,那麼就要先到註冊中心獲取服務提供者的地址,拿到地址後,通過微服務容器內部的簡單負載均衡期進行路由用。

Eureka Server特點:

  • Eureka Client會緩存服務註冊信息
  • Eureka Server的註冊信息只存儲在內存中
  • Eureka的註冊只針對application級別,不支持更細粒度的服務註冊,如單個服務Rest
  • 服務每隔30秒向Eureka Server發送心跳,不建議修改心跳時間。Eureka用這個時間來判斷集群內是否存在大範圍的服務通信異常
  • 如果在15分鐘內有85%的服務沒有被續約,則Eureka Server停止移除已註冊的服務,以保障已註冊的服務信息不丟失
  • Eureka Server之間的數據同步,採用全量拉取,增量同步的方式
  • Eureka 滿足分佈式事務中的CAP理論中的AP

5.4 集中式配置管理

大火的‘微服務架構’詳解與實踐

微服務分佈式環境下,一個系統拆分為很多個微服務,一定要告別運維手工修改配置配置的方式。需要採用集中配置管理的方式來提升運維的效率。
配置文件主要有運行前的靜態配置和運行期的動態配置兩種。

  • 靜態配置通常是在編譯部署包之前設置好。
  • 動態配置則是系統運行過程中需要調整的系統變量或者業務參數。

要想做到集中的配置管理,那麼需要注意以下幾點。

  • 配置與介質分離,這個就需要通過制定規範的方式來控制。
  • 配置的方式要統一,格式、讀寫方式、變更熱更新的模式儘量統一,要採用統一的配置框架。
  • 需要運行時需要有個配置中心來統一管理業務系統中的配置信息。

概念抽象:
介質,是源碼編譯後的產物與環境無關,多環境下應該是可以共用的如:jar

5.5 統一認證鑑權

大火的‘微服務架構’詳解與實踐

安全認證方面,我們基於Spring Security OAuth2 + JWT做安全令牌,實現統一的安全認證與鑑權,使得微服務之間能夠按需隔離和安全互通。
認證鑑權一定是個公共的服務,而不是多個系統各自建設。

5.6 分佈式調用

微服務架構下,相對於傳統部署方式,存在更多的分佈式調用,那麼“如何在不確定的環境中交付確定的服務”,這句話可以簡單理解為,我所依賴的服務的可靠性是無法保證的情況下,我如何保證自己能夠正常的提供服務,不被我依賴的其他服務拖垮?
我們採用的方案:

  • 合理的超時時間
  • 合理的重試機制
  • 合理的異步機制
  • 合理的限流機制(調用次數和頻率)
  • 合理的降級機制
  • 合理的熔斷機制

推薦SEDA架構來解決這個問題。


SEDA : staged event-driven architecture本質上就是採用分佈式事件驅動的模式,用異步模擬來同步,無阻塞等待,再加上資源分配隔離結起來的一個解決方案。

大火的‘微服務架構’詳解與實踐

5.7 分佈式事務

分佈式事務-CAP

  • C 分佈式環境下多個節點的數據是否強一致
  • A 分佈式服務能一直保證可用狀態
  • P 網絡分區的容錯性
大火的‘微服務架構’詳解與實踐

分佈式事務-策略

  • 避免跨庫事務,儘可能相關表在同一個DB
  • 2PC 3PC TCC 補償模式等, 耗時且複雜
  • 基於MQ的最終一致性 簡單、高效、易於理解
  • 將遠程分佈式事務拆解成一系列本地的事務

分佈式事務-基於MQ

大火的‘微服務架構’詳解與實踐

5.8 服務拆分

服務拆分方式

大火的‘微服務架構’詳解與實踐

AKF擴展立方體,是抽象總結的應用擴展的三個維度。

  • X軸 擴展部署實例,就是講單體系統多運行幾個實例,做個集群加負載均衡的模式。
  • Y軸 業務領域分離,就是基於不同的業務拆分。
  • Z軸 數據隔離分區,比如共享單車在用戶量激增時,集群模式撐不住了,那就按照用戶請求的地區進行數據分區,北京、上海、深圳等多建幾個集群。

服務拆分要點

  • 低耦合、高內聚:一個服務完成一個獨立的功能
  • 按照團隊結構:小規模團隊維護,快速迭代

5.9 數據庫拆分

單庫單表難以支撐日益增長的業務量和數據量,服務拆分了數據庫也跟著拆分。


5.9.1 模式

  • 垂直拆分
  • 水平拆分

5.9.2 原則

  • 儘可能不拆分
  • 避免跨庫事務
  • 單表量級1000w
  • 避免垮褲join(冗餘、全局表)

大火的‘微服務架構’詳解與實踐

5.10 日誌管理

日誌主要有三種,系統日誌,業務日誌,跟蹤日誌。有了這些日誌,在出問題的時候能夠幫助我們獲取一些關鍵信息進行問題定位。
要想做到,出了問題能夠追根溯源,那麼我們需要一個可以將整個完整的請求調用鏈串聯起來的標識,這個標識能夠讓我們快速定位問題發生的具體時間地點以及相關信息,能夠快速還原業務交易全鏈路。對這些日誌與流水的細節處理,對於系統運維問題定位有非常大的幫助。通常開源框架只是提供基礎的框架,而設計一個平臺則一定要考慮直接提供統一規範的基礎能力。

分佈式跟蹤

大火的‘微服務架構’詳解與實踐

大火的‘微服務架構’詳解與實踐

大火的‘微服務架構’詳解與實踐

5.11 服務契約與API管理

大火的‘微服務架構’詳解與實踐

對於前面提到的微服務帶來的依賴管理問題,我們需要提供API管理能力。說到API管理,那首先就用提到服務契約。
服務契約,主要描述服務接口的輸入輸出規格標準和其他一些服務調用集成相關的規格內容。

5.12 服務契約與服務模擬

大火的‘微服務架構’詳解與實踐

有了服務契約,研發人員就可以方便的獲取到依賴服務變更的情況,能夠及時的根據依賴服務的變化調整自己的程序,並且能夠方便的進行模擬測試驗證。
根據契約生成模擬服務也就是我們常說的服務擋板,這樣即使依賴的其他服務還無法提供功能,我們也可以通過擋板來進行聯調測試。

5.13 微服務容器

大火的‘微服務架構’詳解與實踐

我們要做穩定、高效、易擴展的微服務應用,實際上我們需要做的事情還是非常多的。如果沒有一個統一的微服務容器,這些能力在每個微服務組件中都需要建設一遍,也很難集成到一起。有了統一的微服務運行容器和一些公共的基礎服務,前面所提到的微服務架構下部分組件重複建設的問題也迎刃而解。

5.14 持續集成與持續部署

大火的‘微服務架構’詳解與實踐

在運維方面,首先我們要解決的就是持續集成和持續交付,能夠方便的用持續集成環境把程序編譯成介質包和部署包並持續穩定的部署到每個環境。
概念抽象:
介質:是源碼編譯後的產物與環境無關,多環境下應該是可以共用的。如:jar
配置:則是環境相關的信息。
部署包=配置+介質。

5.15 微服務平臺與容器雲、DevOps的關係

大火的‘微服務架構’詳解與實踐

就微服務應用平臺本身來說,並不依賴DevOps和容器雲,開發好的部署包可以運行在物理機、虛擬機或者是容器中。然而當微服務應用平臺結合了DevOps和容器雲之後,我們就會發現,持續集成和交付變成了一個非常簡單便捷並且又可靠的過程。簡單幾步操作,整套開發、測試、預發或者生產環境就能夠搭建完成。
整個過程的複雜度都由平臺給屏蔽掉了,通過三大基礎環境的整合,我們能夠使分散的微服務組件更簡單方便的進行統一管理和運維交付。

5.16 技術團隊的組織

技術團隊組織 – 小團隊

大火的‘微服務架構’詳解與實踐

根據“康威定律”,軟件架構是由組織的架構決定的,因此按照貝索斯“two-pizza”團隊的理論和敏捷方法,構建小的團隊,可以有效減少溝通成本,有利於團隊的自治。
我們通過讓一個小的團隊有比較全面的建制,Leader(熟悉業務和技術)+ 前端工程師 + 後端工程師,往往可以能夠比較獨立地承接一個或者幾個業務的工作。這樣團隊成員整體負責一個或者幾個業務模塊,可以極大地提高團隊成員的參與感、使命感和責任感,團隊成員相互幫助,高度自治,大家要麼一起成功,要麼一起失敗。

技術團隊組織 – 團隊劃分

大火的‘微服務架構’詳解與實踐

團隊的劃分,是按照業務線劃分的。隨著業務的複雜度的增加,可以按照業務/子業務線的方式來劃分團隊,但並不是絕對的扁平化,而是嚴格遵循two-pizza原則。
業務線的劃分常常按業務細分,技術團隊要負責支持全部業務線,因此技術團隊的劃分通常按系統或者是業務,Two pizza團隊的原則在組織層級的任何部分都適用,當人數過多時,必須繼續拆分。

技術團隊組織 – 團隊合作

大火的‘微服務架構’詳解與實踐

技術團隊組織 – 結果導向

  1. 主人翁意識(Ownership)
  2. 行動力(Bias for Action)
  3. 吃自己的狗糧(Eat your dog food)
    • 工程師負責從需求調研、設計、開發、測試、部署、維護、監控、功能升級等一系列的工作,也就是說軟件工程師負責應用或者服務的全生命週期的所有工作

    • 運維是團隊成員的第一要務,在強大的自動化運維工具的支撐下,軟件工程師必須負責服務或者應用的SLA
  4. 開發人員參與架構設計,而不是架構師參與開發
    • 研發人員是Owner,對業務和團隊負責
    • 強調抽象和簡化,將複雜的問題分解成簡單的問題,並有效解決,避免過度設計
    • 鼓勵用新技術解決問題,但強調掌控力

六、微服務架構設計過程中積累的心得

  • 深入理解業務
  • 設計階段要追求完美,實踐階段要考慮實際情況作出平衡
  • 容錯能力
  • 監控先行
  • 任何上線可回滾

七、總結

微服務架構是技術升級,但更多的是管理模式的升級、思維方式的轉變。


分享到:


相關文章: