大數據

微服務架構的基礎設施

一、服務發現
微服務種類和數量很多,如果這些信息全部通過手工配置的方式寫入各個微服務節點,首先配置工作量很大,配置文件可能要配幾百上千行,幾十個節點加起來後配置項就是幾萬幾十萬行了,人工維護這麼大數量的配置項是一項災難;其次是微服務節點經常變化,可能是由於擴容導致節點增加,也可能是故障處理時隔離掉一部分節點,還可能是採用灰度升級,先將一部分節點升級到新版本,然後讓新老版本同時運行。不管哪種情況,我們都希望節點的變化能夠及時同步到所有其他依賴的微服務。如果採用手工配置,是不可能做到實時更改生效的。因此,需要一套服務發現的系統來支撐微服務的自動註冊和發現。
服務發現主要有兩種實現方式:自理式和代理式。
1、自理式
自理式結構如下:
image.png

自理式結構就是指每個微服務自己完成服務發現。例如,圖中 SERVICE INSTANCE A 訪問 SERVICE REGISTRY 獲取服務註冊信息,然後直接訪問 SERVICE INSTANCE B。
自理式服務發現實現比較簡單,因為這部分的功能一般通過統一的程序庫或者程序包提供給各個微服務調用,而不會每個微服務都自己來重複實現一遍;並且由於每個微服務都承擔了服務發現的功能,訪問壓力分散到了各個微服務節點,性能和可用性上不存在明顯的壓力和風險。
2. 代理式
代理式結構如下:
image.png

代理式結構就是指微服務之間有一個負載均衡系統(圖中的 LOAD BALANCER 節點),由負載均衡系統來完成微服務之間的服務發現。
代理式的方式看起來更加清晰,微服務本身的實現也簡單了很多,但實際上這個方案風險較大。第一個風險是可用性風險,一旦 LOAD BALANCER 系統故障,就會影響所有微服務之間的調用;第二個風險是性能風險,所有的微服務之間的調用流量都要經過 LOAD BALANCER 系統,性能壓力會隨著微服務數量和流量增加而不斷增加,最後成為性能瓶頸。因此 LOAD BALANCER 系統需要設計成集群的模式,但 LOAD BALANCER 集群的實現本身又增加了複雜性。
不管是自理式還是代理式,服務發現的核心功能就是服務註冊表,註冊表記錄了所有的服務節點的配置和狀態,每個微服務啟動後都需要將自己的信息註冊到服務註冊表,然後由微服務或者 LOAD BALANCER 系統到服務註冊表查詢可用服務。
二、服務路由
有了服務發現後,微服務之間能夠方便地獲取相關配置信息,但具體進行某次調用請求時,我們還需要從所有符合條件的可用微服務節點中挑選出一個具體的節點發起請求,這就是服務路由需要完成的功能。
服務路由和服務發現緊密相關,服務路由一般不會設計成一個獨立運行的系統,通常情況下是和服務發現放在一起實現的。對於自理式服務發現,服務路由是微服務內部實現的;對於代理式服務發現,服務路由是由 LOAD BALANCER 系統實現的。無論放在哪裡實現,服務路由核心的功能就是路由算法。常見的路由算法有:隨機路由、輪詢路由、最小壓力路由、最小連接數路由等。
三、服務容錯
系統拆分為微服務後,單個微服務故障的概率變小,故障影響範圍也減少,但是微服務的節點數量大大增加。從整體上來看,系統中某個微服務出故障的概率會大大增加,如果不及時處理故障,故障擴散開來就會導致看起來系統中很多服務節點都故障了,因此需要微服務能夠自動應對這種出錯場景,及時進行處理。否則,如果節點一故障就需要人工處理,投入人力大,處理速度慢;而一旦處理速度慢,則故障就很快擴散,所以我們需要服務容錯的能力。
常見的服務容錯包括請求重試、流控和服務隔離。通常情況下,服務容錯會集成在服務發現和服務路由系統中。
四、服務監控
系統拆分為微服務後,節點數量大大增加,導致需要監控的機器、網絡、進程、接口調用數等監控對象的數量大大增加;同時,一旦發生故障,我們需要快速根據各類信息來定位故障。這兩個目標如果靠人力去完成是不現實的。舉個簡單例子:我們收到用戶投訴說業務有問題,如果此時採取人工的方式去搜集、分析信息,可能把幾十個節點的日誌打開一遍就需要十幾分鍾了,因此需要服務監控系統來完成微服務節點的監控。
服務監控的主要作用有:
• 實時蒐集信息並進行分析,避免故障後再來分析,減少了處理時間。
• 服務監控可以在實時分析的基礎上進行預警,在問題萌芽的階段發覺並預警,降低了問題影響的範圍和時間。
通常情況下,服務監控需要蒐集並分析大量的數據,因此建議做成獨立的系統,而不要集成到服務發現、API 網關等系統中。
五、服務跟蹤
服務監控可以做到微服務節點級的監控和信息收集,但如果我們需要跟蹤某一個請求在微服務中的完整路徑,服務監控是難以實現的。因為如果每個服務的完整請求鏈信息都實時發送給服務監控系統,數據量會大到無法處理。
服務監控和服務跟蹤的區別可以簡單概括為宏觀和微觀的區別。例如,A 服務通過 HTTP 協議請求 B 服務 10 次,B 通過 HTTP 返回 JSON 對象,服務監控會記錄請求次數、響應時間平均值、響應時間最高值、錯誤碼分佈這些信息;而服務跟蹤會記錄其中某次請求的發起時間、響應時間、響應錯誤碼、請求參數、返回的 JSON 對象等信息。
目前無論是分佈式跟蹤還是微服務的服務跟蹤,絕大部分請求跟蹤的實現技術都基於 Google 的 Dapper 論文《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》。
六、服務安全
系統拆分為微服務後,數據分散在各個微服務節點上。從系統連接的角度來說,任意微服務都可以訪問所有其他微服務節點;但從業務的角度來說,部分敏感數據或者操作,只能部分微服務可以訪問,而不是所有的微服務都可以訪問,因此需要設計服務安全機制來保證業務和數據的安全性。
服務安全主要分為三部分:接入安全、數據安全、傳輸安全。通常情況下,服務安全可以集成到配置中心繫統中進行實現,即配置中心配置微服務的接入安全策略和數據安全策略,微服務節點從配置中心獲取這些配置信息,然後在處理具體的微服務調用請求時根據安全策略進行處理。由於這些策略是通用的,一般會把策略封裝成通用的庫提供給各個微服務調用。基本架構如下:
image.png

七、自動化測試
微服務將原本大一統的系統拆分為多個獨立運行的“微”服務,微服務之間的接口數量大大增加,並且微服務提倡快速交付,版本週期短,版本更新頻繁。如果每次更新都靠人工迴歸整個系統,則工作量大,效率低下,達不到“快速交付”的目的,因此必須通過自動化測試系統來完成絕大部分測試迴歸的工作。
自動化測試涵蓋的範圍包括代碼級的單元測試、單個系統級的集成測試、系統間的接口測試,理想情況是每類測試都自動化。如果因為團隊規模和人力的原因無法全面覆蓋,至少要做到接口測試自動化。
八、自動化部署
相比大一統的系統,微服務需要部署的節點增加了幾倍甚至十幾倍,微服務部署的頻率也會大幅提升(例如,我們的業務系統 70% 的工作日都有部署操作),綜合計算下來,微服務部署的次數是大一統系統部署次數的幾十倍。這麼大量的部署操作,如果繼續採用人工手工處理,需要投入大量的人力,且容易出錯,因此需要自動化部署的系統來完成部署操作。
自動化部署系統包括版本管理、資源管理(例如,機器管理、虛擬機管理)、部署操作、回退操作等功能。
九、配置中心
微服務的節點數量非常多,通過人工登錄每臺機器手工修改,效率低,容易出錯。特別是在部署或者排障時,需要快速增刪改查配置,人工操作的方式顯然是不行的。除此以外,有的運行期配置需要動態修改並且所有節點即時生效,人工操作是無法做到的。綜合上面的分析,微服務需要一個統一的配置中心來管理所有微服務節點的配置。
配置中心包括配置版本管理(例如,同樣的微服務,有 10 個節點是給移動用戶服務的,有 20 個節點給聯通用戶服務的,配置項都一樣,配置值不一樣)、增刪改查配置、節點管理、配置同步、配置推送等功能。
十、接口框架
微服務提倡輕量級的通信方式,一般採用 HTTP/REST 或者 RPC 方式統一接口協議。但在實踐過程中,光統一接口協議還不夠,還需要統一接口傳遞的數據格式。例如,我們需要指定接口協議為 HTTP/REST,但這還不夠,還需要指定 HTTP/REST 的數據格式採用 JSON,並且 JSON 的數據都遵循如下規範。
image.png

如果我們只是簡單指定了 HTTP/REST 協議,而不指定 JSON 和 JSON 的數據規範,那麼就會出現這樣混亂的情況:有的微服務採用 XML,有的採用 JSON,有的採用鍵值對;即使同樣都是 JSON,JSON 數據格式也不一樣。這樣每個微服務都要適配幾套甚至幾十套接口協議,相當於把曾經由 ESB 做的事情轉交給微服務自己做了,這樣做的效率顯然是無法接受的,因此需要統一接口框架。
接口框架不是一個可運行的系統,一般以庫或者包的形式提供給所有微服務調用。例如,針對上面的 JSON 樣例,可以由某個基礎技術團隊提供多種不同語言的解析包(Java 包、Python 包、C 庫等)。
十一、API 網關
系統拆分為微服務後,內部的微服務之間是互聯互通的,相互之間的訪問都是點對點的。如果外部系統想調用系統的某個功能,也採取點對點的方式,則外部系統會非常“頭大”。因為在外部系統看來,它不需要也沒辦法理解這麼多微服務的職責分工和邊界,它只會關注它需要的能力,而不會關注這個能力應該由哪個微服務提供。
除此以外,外部系統訪問系統還涉及安全和權限相關的限制,如果外部系統直接訪問某個微服務,則意味著每個微服務都要自己實現安全和權限的功能,這樣做不但工作量大,而且都是重複工作。
綜合上面的分析,微服務需要一個統一的 API 網關,負責外部系統的訪問操作。
API 網關是外部系統訪問的接口,所有的外部系統接⼊系統都需要通過 API 網關,主要包括接入鑑權(是否允許接入)、權限控制(可以訪問哪些功能)、傳輸加密、請求路由、流量控制等功能。

Leave a Reply

Your email address will not be published. Required fields are marked *