

摘要:本文首先分析傳統的單體架構進而解釋微服務架構以及分布式環境下四層架構,詳細分析了遷移需解決的關鍵問題如服務間通信機制、數據最終一致性等;然后分析了分布式系統核心問題和DevOps基本原則,以此為設計依據提出微服務架構基礎設施總體設計,并且對其關鍵組件如服務注冊與發現、持續交付平臺、服務網關的實施提出具體方案;最后針對微服務架構基礎設施在運維管理中的應用場景進行了探討,說明了微服務架構設計思想優于單體架構設計思想。
關鍵詞:軟件工程;微服務;服務注冊與發現;持續交付
中圖分類號:TP311.5 文獻標識碼:A DOI:10.3969/j.issn.1003 6970.2016.05.023
本文著錄格式:蔣勇.基于微服務架構的基礎設施設計卟軟件,2016,37(5):93-97
0.引言
理論上任何業務系統如果長期存在的話,隨著此系統業務變更、功能增加必然會不斷演變,在一個更大的分布式環境中,這種改變尤其明顯,那么就需要架構分析設計時更多的考慮系統所處的生態環境建設,這樣才能使得整個系統不斷進化。隨著虛擬化技術的發展以及docker容器實踐逐漸完善,微服務架構的設計思想逐漸浮出水面,形成分布式環境下新的最重要的設計思想。文獻對分布式環境下資源及應用平臺進行了研究,但對于應用自身依賴的基礎設施建設沒有討論。本文將詳細探討如何基于微服務架構進行基礎設施建設的設計與分析。
1.從分布式單體架構到微服務架構遷移
1.1分布式單體架構
分布式單體架構指的是在分布式環境下直接部署運行一個整體開發的應用,由整體應用來提供系統所需的服務,它在技術上通常采用分層實現,大致分為表現層、應用層、數據層,它有天然的優勢:它是模塊獨立無關的,各層之間是技術分離的;它有統一的技術棧和開發標準;它通常在一個進程中運行,模塊相互之間協同消耗極小。
但是,在分布式環境下,隨著系統功能的增加,系統越來越復雜,單體架構存在一些必然的缺陷:首先,由于整個系統是一個完整整體,必須重復部署多個才能提高系統性能,而往往系統瓶頸僅僅由于其中某一個或幾個功能過載產生,這就極大浪費了運行環境資源;其次,由于系統功能的變更和演變,某一個功能的變化可能影響其它功能的正常結果,也帶來重新部署和運維管理的復雜性,持續集成變得極為困難;最后,由于整個系統采用統一的技術棧和開發標準,必然使得技術本身的多樣性受到限制,造成解決問題的方法和開發方式存在一定的局限性,當整合外部服務、開放內部服務時也帶來一些技術實現的復雜性。
由此可知,在分布式環境下原有的整體開發的單體架構有必要改進、變化。
1.2微服務架構
1.2.1微服務架構定義
微服務架構是一種新的軟件體系設計模式,它并沒有形成統一、嚴格的定義,但是基于其分布式環境應用的場景,卻擁有一些共同的特征:比如開發敏捷性、持續交付、可伸縮性、最終一致性等。
微服務架構建議將大型復雜的單體架構應用劃分為一組微小的服務,每個微服務根據其負責的具體業務職責提煉為單一的業務功能;每個服務可以很容易地部署并發布到生產環境里隔離和獨立的進程內部,它可以很容易地擴展和變更;對于一個具體的服務來說可以采用任何適用的語言和工具來快速實現;服務之間基于基礎設施互相協同工作。
1.2.2分布式四層架構定義
由美國視頻服務企業netflix提出的“engagement platform”支持分布式的四層架構,是目前采用微服務架構的最成功實踐,它能很好的適用于大規模應用運行環境,滿足更高的性能要求。分析理想的分布式四層架構如圖1所示。
分布式四層架構的每層功能如下:
1)顯示層:這一層主要是把系統提供的各類服務展現給用戶,支持用戶通過界面與系統進行友好的交互,也支持管理員通過界面對系統進行監控管理。
2)分發層:這一層主要針對用戶或者其它系統發出的請求進行預處理,并根據策略決定路由到何處去進行處理,從而達到分發控制的目的,并且根據請求峰值采取負載均衡擴展策略或者相應熔斷限流策略。
3)聚合層:這一層負責提供基于各類原子基礎服務的集成、編排、組合,并且包含各類數據的清洗、采集、轉換;提供可以動態變更策略的服務訪問控制功能(如授權機制、角色分配、緩存、數據一致性等);提供輕量級的通信機制或者采用統一默認調用規則使得各類服務之間容易協同合作。
4)服務層:這一層提供不可分割的、最小原子的、單一業務功能的服務,每一個服務部署在獨立的、隔離的運行環境,可以方便的替換和擴展,對上層提供基礎API調用接口支持。
1.3遷移需解決問題
在分布式環境下,從單體架構遷移到微服務架構需要解決很多問題:首先需要一種設計理念的轉變,根據職責分離的原則把大的復雜的業務邏輯抽象成更小的原子的可重復利用的服務,并且盡可能的減少流程緊密聯系的業務邏輯拆分;其次需要從服務這個角度出發考慮業務邏輯的設計實現,進而考慮服務的定位、編排和訪問控制如何優雅的實現;最后需要考慮的是這些微服務的可持續交付以及后端數據最終一致性問題。從單體應用遷移到微服務應用如圖2所示:
1.3.1如何處理服務狀態
在分布式環境下盡可能的設計無狀態的微服務更容易實現可伸縮性,但是在很多應用場景(用戶相關數據讀寫)有狀態是不可避免的,所以必須把有狀態服務的狀態相關信息提取出來使得有狀態服務達到無狀態服務同樣的性能和擴展能力。目前有兩種實現方式:一種是采用分布式緩存集群存儲狀態,一種是采用nosql數據庫集群來存儲狀態。
1.3.2服務之間通信機制
由于每個微服務都是在獨立、隔離的進程內部運行,所以這些微服務之間的調用行為屬于進程間通信。服務之間通信機制需要考慮以下幾點:
1)服務標識:每個微服務需要通過類似語義定義語言來準確的描述標識一個服務的API,還需要考慮到服務升級和多版本共存如何描述,保證向前兼容;
2)服務并發情況:服務之間的調用方式存在兩種響應方式:一個服務的請求會有一個服務實例響應,一個服務的請求會有多個服務實例響應。如果是并發就需要考慮如何實現并描述服務并發觸發機制以及并發策略;
3)處理部分失效:當服務被調用時可能存在調用超時或者得不到響應因而產生調用堵塞并且占用資源,處理這類情況需要根據不同場景采取不同策略,比如超時重試策略、熔斷限流策略、最近失敗緩存等。
4)同步請求/響應模式:基于http的REST,基于RPC和序列化支持多種消息格式的Thrift,二進制格式的Protocol Buffer、Avro。
5)異步消息通信模式:實現AMQP的RabbitMQ、Apache的Kafka。
6)服務執行結果緩存:隨著系統性能要求的增長或者服務被重復調用的需要,在一定時間間隔緩存服務執行結果存在一定必要性。
1.3.3服務注冊與發現機制
如何進行服務定位就涉及到服務的注冊與發現機制,這就需要提供一個高性能、高可用、實時更新的服務注冊與發現中心或者提供智能終端和啞管道。
服務注冊有自注冊/被注冊兩種方式。自注冊:由服務實例自己到服務注冊與發現中心注冊或注銷,并且通過心跳通訊來確認注冊信息有效性。被注冊:由服務注冊與發現中心來確認服務的注冊與注銷,它常常通過查詢服務實例部署信息或者通過訂閱服務實例部署事件來發現一個新的服務實例,并跟蹤其運行狀態確認注銷終止的服務實例。
服務發現有兩種場景:服務調用者發現/分發層服務發現。
1)服務調用者發現場景:服務調用者直接向服務注冊與發現中心請求查詢,獲得可用的服務,根據默認規則或者負載均衡策略從與此服務對應的多個服務實例中選擇請求對象發出請求。這種場景就需要提供客戶端框架。
2)分發層服務發現場景:客戶端向分發層提出請求,分發層處理請求時首先向服務注冊與發現中心發出查詢獲取查詢結果,然后依據分發路由策略將每個請求轉發往可用的服務實例。這種場景需要服務端框架。
1.3.4服務可持續交付
實現微服務架構的保障就是能夠嚴格執行服務的可持續交付,服務可持續交付指的是每個服務交付的流程具備持續性,也就是說一個微服務應用從開發完畢到部署發布中間的過程是一個可持續的過程,并且這個微服務應用可能存在多個版本不同運行狀態的服務實例,它們需要集成到現有的運行環境中穩定提供服務。服務可持續交付常常包括幾個方面:開發、單元測試、構建、部署、集成、集成測試、發布,從基礎設施環境來看又包含幾個部分:代碼版本管理、構建管理、部署管理、集成管理、測試管理、發布管理、運維監控管理。
1.3.5數據最終一致性
數據最終一致性指的是數據對象在沒有新的更新之前,最終所有獲取數據的請求都將返回最后更新的值,在分布式環境微服務架構下,為了保證每個微服務的可伸縮性和獨立性,為了保證微服務之間的松散耦合,不同的微服務都有自己的數據源并且可能使用不同類型的數據庫(nosql或者關系型數據庫),這種去中心的分布式數據管理使得實現多個服務之間的事務型事務變得極為困難,因為如果這種多階段事務執行中任何一個階段失敗都會造成數據不一致(事務回滾非常復雜),這就需要一種方案既保證多服務之間的事務型事務執行時業務交易的數據一致性又保證從多個服務獲取一致性數據的高可用性。
一種方案是多個微服務應用訪問同一個數據庫或者把多個微服務應用邏輯上歸并為一個微服務應用開發,這里就需要在業務邏輯拆分時進行權衡,對于那些頻繁訪問或者流程緊密聯系的業務功能不進行拆分而作為一個微服務進行設計開發。
另一種方案是使用事件驅動框架和消息隊列來完成多個服務之間的事務型事務,其流程是把跨多服務的事務分解為若干步驟,每一個步驟會發布一個激活下一個步驟的事件,任何一個步驟失敗代表整個事務失敗,必須保證對數據的修改能夠通過事務補償運算來實現邏輯回滾。這種方案的優點是異步且事務吞吐量大、容錯性好,其缺點是開發較為復雜。
2.微服務架構基礎設施設計與分析
2.1微服務架構基礎設施設計依據
2.1.1分布式系統核心問題
1)性能和可伸縮性
在分布式環境下,微服務架構使得業務邏輯可以拆分為粒度較小的服務,這些服務能夠運行在獨立、隔離的環境,易于部署、可擴展性強,因此這些微服務的處理請求能力可伸縮性強,性能優勢明顯。
2)數據一致性和高可用性
在分布式環境下,從硬件到主機操作系統到軟件總有一部分存在故障狀態,需要保證這個系統的高可用性就需要盡可能的減少系統資源開銷的同時排除單點故障或者容忍錯誤;然而在故障恢復或者多點備份或者執行多服務事務的同時也需要保證數據的一致性,基于性能優先的考慮這種數據一致性是數據最終一致性。
2.1.2DevOps基本原則
DevOps指的是從軟件交付的全局出發在開發和運維架起交流和協作的橋梁,并且自動化配置管理軟件的文化變革運動,DevOps的重要組成部分就是持續交付,其基本原則是使軟件交付的流程自動化且可持續,并盡可能簡潔。
2.2微服務架構基礎設施總體設計
通過分析在分布式環境下從單體架構遷移到微服務架構需要解決的問題以及微服務架構基礎設施的設計依據,得到微服務架構基礎設施總體設計如圖3所示。
其中,開發完畢的微服務應用經由持續交付平臺部署、驗證、發布到分布式環境中,同時把這個微服務注冊到服務注冊中心,用戶或外部服務通過服務網關訪問此分布式環境節點中的API服務,服務網關通過服務注冊中心發現服務。其他一些基礎設施提供對這些微服務的運行監控管理。
2.3微服務架構基礎設施關鍵組件
2.3.1持續交付平臺
實現一個可持續交付平臺的目的是把基于分布式環境分析設計的微服務應用快速靈活、可重復且持續的、自動化的集成部署到分布式環境中穩定運行,并且這些微服務是可編程配置、易于維護、變更、擴展的,其可以運行于一個獨立、隔離的容器里表現為一個進程。持續交付流程如圖4所示。
一個可持續交付平臺主要包含兩部分內容:
1)軟硬件資源管理功能:它主要管理整個分布式環境中的軟硬件資源如何合理進行邏輯劃分利用,這些資源包括主機資源(內存、硬盤、磁盤陣列、CPU)、網絡設施(路由、虛擬網絡)、容器實例(微服務實例)等。
2)持續交付流程引擎:通過定義可持續交付流程的各個階段節點以及觸發條件,并且提供默認執行規則和策略或者人工配置選項設置來實現一個微服務實例的構建、集成、部署流程,通過心跳檢測或其它手段監控微服務實例健康狀況并且可在期望閾值時觸發相應響應事件。
目前開源可借鑒產品有:Jenkins、Netflix的Spinnaker、ThoughtWorks的Go等。
2.3.2服務注冊與發現組件
服務注冊與發現是微服務架構中的核心組件,分布式環境中服務的實例會根據運行環境變化依據默認規則或策略動態變化,這時要實現服務注冊與發現變得異常復雜,它常常需要提供以下功能:
1)注冊和標識服務:一個服務一旦從可持續交付平臺部署運行起來就成為一個服務實例服務實例最終是需要被用戶或其它服務訪問的,那么需要一個服務注冊中心記錄服務實例的位置信息屬性、訪問路徑、認證證書、訪問協議、版本號以及其它訪問相關信息。可以通過在部署流程結束時向服務注冊中心自動注冊服務實例。標識一個服務的服務實例那么意味著首先需要標識一個服務。一個服務實例和服務的不同之處在于服務實例是有位置信息和部署相關信息的,而且一個服務實例是有健康狀態的也是有生命周期的,一個服務可以有多個版本,每個版本的服務對應多個服務實例,每個版本的服務對應一個部署流程。服務注冊中心追蹤服務實例的運行狀態,服務實例隨著自身健康狀態的變化以及網絡環境的變化其位置信息會動態變化。一個版本的服務它的服務實例在運行環境中動態部署多少個需要配置相應閾值觸發策略。
2)定位和發現服務:當用戶從客戶端直接訪問時,分發層會查詢服務注冊中心發現可訪問的服務并根據負載均衡算法轉發到相應的服務實例。從分發層來看,服務層提供的服務是單個服務,聚合層提供的服務是多個服務的編排組合。分發層需要根據請求負載和活著的服務實例數量決定負載均衡算法或者擴展已有的服務實例。更多的場景是多個微服務協同合作時如何定位和發現服務。這時調用者如果不經過分發層而是直接訪問服務層的服務,那么調用者查詢服務注冊中心發現可訪問的服務以及與之對應的服務實例,然后設置相應的負載均衡算法調用相應的服務實例。
目前開源可借鑒產品有:Netflix的Eureka、Etcd、Consul等。
2.3.3服務網關
服務網關是一個統一調用邏輯人口,封裝了分布式環境中某個節點內部的服務信息。服務網關的實現有幾部分:
1)支持對已有的服務注冊中心注冊的服務直接暴露給外部調用。
2)對于客戶端展現需要調用的多個服務的場景開發新的服務使得客戶端一次請求獲得多個服務的組合結果。
3)支持對請求預處理、規則匹配,比如認證、授權判斷等。
4)支持為某些一定時間間隔執行結果不變的服務請求提供緩存存儲,并且對服務請求部分失效提供最后一次正確執行的緩存結果或者空響應。
5)提供請求分發路由、負載均衡、安全防護、協議轉換等功能。
目前開源的服務網關有:Netflix的Zuul,Mashape的Kong、Tyk等。
3.微服務架構基礎設施在運維管理中的應用
隨著信息化的發展,各類應用系統層出不窮,運維人員管理數量極其龐大的微服務變得十分復雜,因此在分布式環境下應用的可持續交付能力變得極其重要。采用持續交付平臺可以支持微服務自動化的便捷部署到分布式環境中并經過驗證后發布。采用服務注冊中心可以支持微服務的發現與定位,為微服務的集成、組合提供支持。采用服務網關可以對外提供一個分布式環境節點的微服務API統一訪問入口。采用其它基礎設施比如消息總線可以提供微服務之間異步調用支持,任務和資源調度可以提供微服務合理利用分布式環境各類資源。通過在分布式環境下提供各種基礎設施使得整個運維管理更加高效、科學、合理,并且極大的降低了運維成本和復雜性。
4.結論
本文通過分析分布式環境下微服務架構相對于單體架構的優勢以及其遷移需解決問題提出微服務基礎設施總體設計,分析了基礎設施關鍵組件的功能,舉例了其在運維管理中的應用。當然微服務架構的實踐還存在很多待深入研究的問題,比如其在機器學習、大數據挖掘等分布式計算場景的應用,這些還需要今后在實踐中不斷探索、學習。