打造一個企業級應用的微服務開發框架(上)---從服務注冊中心到服務管理中心
近年來越來越多的企業開始實踐微服務,而微服務在企業應用落地的過程,面臨著微服務開發框架的選型,無論是自研還是選擇第三方框架都不得不考慮的問題包括:微服務框架是否具備高可靠性,任何時間不能中斷業務;微服務框架是否能夠實現高速通信性能,保證業務從單體架構向微服務架構切換時,性能下降不會太多。本文從服務管理中心、通信處理兩個模塊來介紹華為開源微服務框架SeviceComb如何幫助企業應用快速具備高性能的通信能力以及高可靠的服務管理能力。上篇先介紹微服務的服務管理中心。
從服務注冊中心到服務管理中心1? ???整體介紹
圖1 ServiceCenter整體介紹
ServiceCenter是一個具有微服務實例注冊/發現能力的微服務組件,提供一套標準的RESTful API對微服務元數據進行管理。ServiceComb的微服務注冊及動態發現能力也是依賴其實現的。
除了以上描述的微服務動態發現外,ServiceCenter幫助應用具備以下能力:
支持微服務實例隔離管理
支持微服務黑白名單管理
支持長連接監聽微服務實例狀態變化
支持OpenAPI規范微服務契約管理
支持微服務依賴關系管理
提供Web portal展示微服務管理界面
高可用的故障處理模型(自我保護機制)
高性能接口和緩存數據設計
2? ???管理的需要
作為微服務系統中非常重要的組件。當前可選來做微服務注冊中心的組件很多,例如Zookeeper、Consul、Eureka、ETCD。然而這些服務注冊中心組件的重點在于解決服務的注冊和發現,也就是一個動態路由的問題。而在一個大型的微服務架構的系統中,除了這些動態路由信息外,還有一些微服務自身的元數據同樣需要進行管理,所以我們定義出微服務靜態元數據。通過ServiceCenter提供的接口可以很方便的檢索微服務信息。
除了微服務本身信息屬于靜態元數據外,ServiceCenter還擴展了微服務依賴關系、黑白名單、Tag標簽和契約信息等元數據,他們之間的關系如下圖所示:
圖2 微服務相關靜態信息之間的關系
這些微服務元數據不僅把實例信息分組管理起來,同時也滿足了用戶對微服務管理的需要。比如說微服務的黑白名單,業界的服務注冊中心大多僅實現了consumer服務依賴的服務實例發現,但沒法對一些安全要求高的服務設置白名單訪問控制,ServiceCenter支持給這類provider服務設置黑白名單過濾規則,防止惡意服務發現并DDoS攻擊。
3? ???分布式系統的高可用性保障
微服務及支撐它運行所需要的系統,從廣義上來看,是一個典型的分布式系統。而分布式系統就一定不能逃脫CAP魔咒:
Consistency(一致性),?在分布式系統的各點同時保持數據的一致。?Availability(可用性),?每個請求都能接受到一個響應,無論響應成功或失敗。Partition tolerance(分區容錯性),當出現網絡分區故障時系統的容錯能力。C和A是每個系統都在努力追求的目標,但是P又是不能完全避免的。想同時滿足三者是不可能的任務。
此后應運而生的BASE理論便成了現代化,特別是互聯網分布式系統設計的準則:BASE理論,Basically Available(基本可用)、Soft state(軟狀態)和Eventually consistent(最終一致性);
ServcieCenter本身作為實現微服務架構中服務注冊發現的組件,對整體微服務系統起到至關重要的作用,并且其本身也是一個分布式的系統。因此后面我們通過對一個微服務系統中常見故障模式的剖析來介紹在CSE中對BASE的實現。
3.1? ? 常見的故障模式
圖3?常見的故障模式
這里列出了ServiceComb架構中常見的故障以及對應的自保護機制,由于后端存儲使用ETCD,本身也有一定的故障恢復能力,具體可以訪問官網了解;現在簡單了解下ServiceComb SDK(簡稱:SDK)和ServiceCenter是如何實現高可用的。
SDK:
1.? ?? ???與ServiceCenter網絡分區:SDK提供實例緩存機制,保證業務繼續可以用。
2.? ?? ???業務實例不可達:SDK提供客戶端負載均衡能力,快速將請求路由到可用的業務實例,同時也支持提供一系列的容錯策略,控制流量繼續流向異常的實例。
ServiceCenter:
1.? ?? ???進程異常:ServiceCenter提供監聽127.0.0.1的本地HTTP健康檢查接口/health,當監控腳本調用該接口時,ServiceCenter內部會進行etcd可用性檢查、當前管理資源容量超限檢查和平均延時等檢查。當以上某個指標發生異常時,接口將返回錯誤,便于監控系統及時感知。
2.? ?? ???環境約束:一般有CPU負載高、內存不足和磁盤空間不足等因素,ServiceCenter針對環境不穩定或資源不足的場景,除了自動觸發自保護機制以外,還有提供一些可定制策略盡量保證自身可服務在這類環境中。如:針對CPU負載高的環境,ServiceCenter支持配置請求讀寫超時,最大限度保證請求可以正常處理完畢,針對磁盤空間資源不夠場景,ServiceCenter自身提供定時日志壓縮轉儲能力,盡量減少磁盤空間占用。
3.? ?? ???并發操作:針對并發向ServiceCenter發寫請求場景,需要保證數據一致。為此ServiceCenter利用了etcd本身提供數據強一致性能力,保證每一次寫操作是原子操作;對于復雜的分布式業務場景,ServiceCenter內部還提供了分布式鎖組件,防止分布式并發寫數據不一致的問題。
4.? ?? ???網絡分區:微服務依賴常見問題,一般是依賴的服務不可用和相互之間網絡故障問題。針對前者,松耦合設計,ServiceComb SDK(簡稱:SDK)和ServiceCenter均有提供緩存機制,保證運行態下,SDK到ServiceCenter、ServiceCenter到etcd各段間互不干擾;針對后者,ServiceCenter除了提供常見的客戶端重試外,還提供異步心跳和自我保護機制。
可見ServiceComb從設計上已經考慮了高可用,下面分別從SDK到ServiceCenter和ServiceCenter到etcd兩個層面來說明ServiceComb如何實現的。
3.2? ??保護機制3.2.1? ?從SDK到ServiceCenter
1.? ?? ???實例緩存機制
基于SDK開發的微服務,會在第一次消費Provider微服務時,會進行一次實例發現操作,此時內部會請求ServiceCenter拉取Provider當前存活的實例集合,并保存到內存緩存當中,后續消費請求就依據該緩存實例集合,按照自定義的路由邏輯發送到Provider的一個實例服務中。
這樣處理的好處是,已經運行態的SDK進程,始終保留一份實例緩存;雖然暫時無法感知實例變化及時刷新緩存,但當重新連上ServiceCenter后會觸發一緩存刷新,保證實例緩存是最終有效的;在此過程中SDK保證了業務始終可用。
圖4 微服務實例緩存機制
2.? ?? ???心跳保活機制
ServiceCenter的微服務實例設計上是存在老化時間的,SDK通過進程上報實例心跳的方式保活,當Provider端與ServiceCenter之間心跳上報無法保持時,實例自動老化,此時ServiceCenter會通知所有Consumer實例下線通知,這樣Consumer刷新本地緩存,后續請求就不會請求到該實例,也就微服務的實現動態發現能力。
這樣做的好處是,解決了業務某個實例進程下線或異常時,依賴其業務的微服務實例,會在可容忍時間內,切換調用的目標實例,相關業務依然可用。
圖5 微服務實例心跳保活機制
3.2.2? ?從ServiceCenter到etcd
1.? ?? ???異步緩存機制
在ServiceCenter內部,因為本身不存儲數據,如果設計上單純的僅作為一個Proxy服務轉發外部請求到etcd,這樣的設計可以說是不可靠的,原因是因為一旦后端服務出現故障或網絡訪問故障,必將導致ServiceCenter服務不可用,從而引起客戶端實例信息無法正確拉取和刷新的問題。所以在設計之初,ServiceCenter引入了緩存機制。
圖6?異步緩存機制
1)? ?? ???啟動之初,ServiceCenter會與etcd建立長連接(watch),并實時監聽資源的變化。
2)? ?? ???每次watch前,為防止建立連接時間窗內發生資源變化,ServiceCenter無法監聽到這些事件,會進行一次全量list查詢資源操作。
3)? ?? ???運行過程中,List & watch所得到的資源變化會與本地緩存比對,并刷新本地緩存。
4)? ?? ???微服務的實例發現或靜態數據查詢均使用本地緩存優先的機制。
異步刷新緩存機制,可以讓ServiceCenter與etcd的緩存同步是異步的,微服務與ServiceCenter間的讀請求,基本上是不會因為etcd不可用而阻塞的;雖然在資源刷新到ServiceCenter watch到事件這段時間內,會存在一定的對外呈現資源數據更新延時,但這是可容忍范圍內的,且最終呈現數據一致;這樣的設計即大大提升了ServiceCenter的吞吐量,同時保證了自身高可用。
2.? ?? ???異步心跳機制
中心化設計,另一個難題是,性能問題,基于心跳保活機制,隨著實例數量增加,ServiceCenter處理心跳的壓力就會越大;要優化心跳處理流程,首先了解下ServiceCenter怎么實現實例心跳的。
實例心跳,主要是為了讓ServiceCenter延長實例的下線時間,在ServiceCenter內部,利用了etcd的KeyValue的lease機制來計算實例是否過期。lease機制的運作方式是,需保證在定義的TTL時間內,發送keepalive請求進行保持存儲的數據不被etcd刪除。基于這個機制,ServiceCenter會給每個實例數據設置下線時間,外部通過調用心跳接口出發ServiceCenter對etcd的keepalive操作,保持實例不下線。
可以知道,這樣設計會導致上報心跳方因etcd延時大而連接阻塞,上報頻率越高,ServiceCenter等待處理連接隊列越長,最終導致ServiceCenter拒絕服務。
圖7 異步心跳機制
在這里ServiceCenter做了一點優化,異步心跳機制。ServiceCenter會根據上報實例信息中的心跳頻率和可容忍失敗次數來推算出最終實例下線時間,比如:某實例定義了30s一次心跳頻率,最大可容忍失敗是3次,在ServiceCenter側會將實例定義為120s后下線。另外,在實例上報第一次心跳之后,ServiceCenter會馬上產生一個長度為1的異步隊列,進行請求etcd,后續上報的心跳請求都會在放進隊列后馬上返回,返回結果是最近一次請求etcd刷新lease的結果,而如果隊列已有在執行的etcd請求,新加入的請求將會丟棄。
這樣處理的好處是持續的實例心跳到ServiceCenter不會因etcd延時而阻塞,使得ServiceCenter可處理心跳的能力大幅度的提高;雖然在延時范圍內返回的心跳結果不是最新,但最終會更新到一致的結果。
3.? ?? ???自我保護機制
前面提到的緩存機制,保證了ServiceCenter在etcd出現網絡分區故障時依然保持可讀狀態,ServiceCenter的自我保護(Self-preservation)機制保證了Provider端與ServiceCenter在出現網絡分區故障時依然保持業務可用。
現在可以假設這樣的場景:全網大部分的Provider與ServiceCenter之間網絡由于某種原因出現分區,Provider心跳無法成功上報心跳。這樣的情況下,在ServiceCenter中會出現大量的Provider實例信息老化下線消息,ServiceCenter將Provider實例下線事件推送到全網大部分的Consumer端,最終導致一個結果,用戶業務癱瘓。可想而知對于ServiceCenter乃至于整個微服務框架是災難性的。
為了解決這一問題,ServiceCenter需要有一個自我保護機制(Self-preservation):
圖8??ServiceCenter的自我保護機制
1)? ?? ???ServiceCenter在一個時間窗內監聽到etcd有80%的實例下線事件,會立即啟動自我保護機制。
2)? ?? ???保護期間內,所有下線事件均保存在待通知隊列中。
3)? ?? ???保護期間內,ServiceCenter收到隊列中實例上報注冊信息則將其從隊列中移除,否則當實例租期到期,則推送實例下線通知事件到consumer服務。
4)? ?? ???隊列為空,則關閉自我保護機制。
有了自我保護機制后,即使etcd存儲的數據全部丟失,這種極端場景下,SDK與ServiceCenter之間可在不影響業務的前提下,做到數據自動恢復。雖然這個恢復是有損的,但在這種災難場景下還能保持業務基本可用。
以上就是ServiceComb的服務管理中心在分布式系統下的高可靠架構設計,在進行大規模、高并發的企業應用開發時,可靠的服務管理中心能夠使得分布式系統運行更加穩定,同時高性能的通信也使得分布式系統更高效地處理密集的業務。下篇我們會對ServiceComb高性能通信進行介紹。
微服務 華為云
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。