您好,登錄后才能下訂單哦!
服務粒度
三個×××手原則,即一個微服務三個人負責開發
從系統規模來講,3個人負責開發一個系統,系統的復雜度剛好達到每個人都能全面理解整個系統,又能夠進行分工的粒度;2個人,系統的復雜度不夠,開發人員可能覺得無法體現自己的技術實力;4個及以上,系統復雜度又無法讓開發人員對系統的細節都了解很深
從團隊管理來說,3個人可以形成一個穩定的備份,即使一個人休假或者調配到其他系統,剩余2個人還可以支撐;2個人壓力太大;一個人就是單點啦
拆分方法
基于“三個×××手”的理論,可以計算出拆分后合適的服務數量
1. 基于業務邏輯拆分
將系統中的業務模塊按照職責范圍識別出來,每個單獨的業務模塊拆分為一個獨立的服務
難點問題在于,對“職責范圍”的理解差異很大。例如,一個電商系統,第一種方式是將服務劃分為“商品”“交易”“用戶”3個服務,第二種方式是劃分為“商品”“訂單”“支付”“發貨”“賣家”“買家”6個服務,哪種方式更合理?
困惑在于從業務的角度來拆分,規模粗和細都沒有問題,因為拆分基礎都是業務邏輯,要判斷拆分粒度,不能從業務邏輯角度,根據“三個×××手”原則,計算一下大概的服務范圍
例如,有10個人,按以上原則,大約需要劃分4個服務,那么“登錄、注冊、用戶信息管理”都可以劃到“用戶服務”職責范圍內;如果團隊規模是100人支撐服務,服務數量可以達到40個,那么“用戶登錄”就是一個服務了;如果團隊規模達到1000人支撐業務,那“用戶連接管理”可能就是一個獨立的服務了
2. 基于可擴展拆分
將系統中的業務模塊按照穩定性排序,將已經成熟和改動不大的服務拆分為穩定服務,將經常變化和迭代的服務拆分為變動服務
穩定的服務粒度可以粗一些,即使邏輯上沒有強關聯的服務,也可以放在同一個子系統中,例如將“日志服務”和“升級服務”放在同一個子系統中;不穩定的服務粒度可以細一些,但不要太細,始終記住要控制服務的總數量
這樣的拆分主要是為了提升項目快速迭代的效率,避免在開發的時候,不小心影響了已有的成熟功能導致線上問題
3. 基于可靠性拆分
將系統中的業務模塊按照優先級排序,將可靠性要求高的核心服務和要求低的非核心服務拆分開來,然后重點保證核心服務的高可用。
好處
避免非核心服務故障影響核心服務
例如,日志上報一般都屬于非核心服務,但是在某些場景下可能有大量的日志上報,如果系統沒有拆分,那么日志上報可能導致核心服務故障;拆分后即使日志上報有問題,也不會影響核心服務
核心服務高可用方案可以更加單
核心服務的功能邏輯更加簡單,存儲的數據可能更少,用到的組件也會更少,設計高可用方案部分情況下要比不拆分簡單很多
能夠降低高可用成本
將核心服務拆分出來后,核心服務占用的機器、帶寬等資源比不拆分要少很多。因此,只針對核心服務做高可用方案,機器、帶寬等成本比不拆分要節省較多
4. 基于性能拆分
將性能要求高或者性能壓力大的模塊拆分出來,避免性能壓力大的服務影響其他服務
常見的拆分方式和具體的性能瓶頸有關,可以拆分Web服務、數據庫、緩存等
例如,電商的搶購,性能壓力最大的是入口的排隊功能,可以將排隊功能獨立為一個服務
以上拆分,可以根據實際情況自由排列組合
基礎設施
“automated”是重要一環,如果其相關的基礎設施不健全,那微服務就是焦油坑,讓研發,測試,運維陷入各種陷阱中
微服務基礎設施如下圖所示
實施微服務
有開源的微服務基礎設施全家桶,例如,Spring Cloud項目,涵蓋了服務發現、服務路由、網關、配置中心等功能
如果微服務的數量并不是很多的話,并不是每個基礎設施都是必須的
按優先級來搭建基礎設施
服務發現、服務路由、服務容錯:這是最基本的微服務基礎設施
接口框架、API網關:主要是為了提升開發效率,接口框架是提升內部服務的開發效率,API網關是為了提升與外部服務對接的效率
自動化部署、自動化測試、配置中心:主要是為了提升測試和運維效率
服務監控、服務跟蹤、服務安全:主要是為了進一步提升運維效率
以上3和4兩類基礎設施,其重要性會隨著微服務節點數量增加而越來越重要,但在微服務節點數量較少的時候,可以通過人工的方式支撐,雖然效率不高,但也基本能夠頂住
自動化測試
微服務將原本大一統的系統拆分為多個獨立運行的“微”服務,微服務之間的接口數量大大增加,并且微服務提倡快速交付,版本周期短,版本更新頻繁
如果每次更新都靠人工回歸整個系統,則工作量大,效率低下,達不到“快速交付”的目的,因此必須通過自動化測試系統來完成絕大部分測試回歸的工作中
自動化測試涵蓋的范圍包括代碼級的單元測試、單個系統級的集成測試、系統間的接口測試,理想情況是每類測試都是自動化
因為團隊規模和人力的原因無法全面覆蓋,至少要做到接口測試自動化
自動化部署
相比大一統的系統,微服務需要部署的節點增加了幾倍甚至十幾倍,微服務部署的頻率也會大幅提升(例如,我們的業務系統70%的工作日都部署操作),綜合計算下來,微服務部署的次數是大一統系統部署次數的幾十倍
這么大的部署操作,如果繼續采用人工手工處理,需要投入大量的人力,且容易出錯,因此需要自動化部署的系統來完成部署操作
自動化部署系統包括版本管理、資源管理(例如,機器管理、虛擬機管理)、部署操作、回退操作等功能
配置中心
微服務的節點數量非常多,通過人工登錄每臺機器手工修改,效率低,容易出錯
特別是部署或者排障時,需要快速增刪改查配置,人工操作的方式顯然是不行的
有的運行期配置需要動態修改并且所有節點即時生效,人工操作是無法做到的
綜上,微服務需要一個統一的配置中心來管理所有微服務節點的配置
配置中心包括配置版本管理(例如,同樣的微服務,有10個節點是給移動用戶服務的,有20個節點給聯通用戶服務的,配置項都一樣,配置值不一樣)、增刪改查配置、節點配置、配置同步、配置推送等功能
接口框架
微服務提倡輕量級的通信方式,一般采用HTTP/REST或者RPC方式統一接口協議
但在實踐過程中,光統一接口協議還不夠,還需要統一接口傳遞的數據格式
例如,我們需要指定接口協議為HTTP/REST,但這還不夠,還需要指定HTTP/REST的數據格式采用JSON,并且JSON的數據都遵循如下規范。
如果我們只是簡單指定了HTTP/REST協議,而不指定JSON和JSON的數據規范,那么就會出現這樣混亂的情況:有的微服務采用XML,有的采用JSON,有的采用鍵值對;即使同樣都是JSON,JSON數據格式也不一樣。這樣每個微服務都要適配幾套甚至幾十套接口協議,相當于把曾經由ESB做的事情轉交給微服務自己做了,這樣做的效率顯然是無法接受的,因此需要統一接口框架
接口框架不是一個可運行的系統,一般以庫或者包的形式提供給所有微服務調用。例如,針對上面的JSON樣例,可以由某個基礎技術團隊提供多種不同語言的解析包(Java包、Python包 、C庫等)
API網關
系統拆分為微服務后,內部的微服務之間是互聯互通的,相互之間的訪問都是點對點的
如果外部系統想調用系統的某個功能,也采取點對點的方式,則外部系統會非常“頭大”
因為在外部系統看來,它不需要也沒辦法理解這么多微服務的職責分工和邊界,它只會關注它需要的能力,而不會關注這個能力應該由哪個微服務提供
外部系統訪問系統還涉及安全和權限相關的限制,如果外部系統直接訪問某個微服務,則意味著每個微服務都要自己實現安全和權限的功能,這樣做不但工作量大,而且都是重復工作
綜合上面的分析,微服務需要一個統一的API網關,負責外部系統的訪問操作
API網關是外部系統訪問的接口,所有的外部系統接入系統都需要通過API網關,主要包括接入鑒權(是否允許接入)、權限控制(可以訪問哪些功能)、傳輸加密、請求路由、流量控制等功能
服務發現
微服務種類和數量很多,如果這些信息全部通過手工配置的方式寫入各個微服務節點,首先配置工作量大,配置文件可能要配幾百上千行,幾十個節點加起來后配置項就是幾萬幾十萬行了,人工維護這么大數量的配置項是一項災難
其次是微服務節點經常變化,可能是由于擴容導致節點增加,也可能是故障處理時隔離掉一部分節點,還可能是采用灰度升級,先將一部分節點升級到新版本,然后讓新老版本同時運行
不管哪種情況,我們都希望節點的變化能夠及時同步到所有其他依賴的微服務。如果采用手工配置,是不可能做到實時更改生效的
因此,需要一套服務發現的系統來支撐微服務的自動注冊和發現
服務發現主要有兩種實現方式:自理式和代理式
1. 自理式
自理式結構如下:
自理式結構就是指每個微服務自己完成服務發現。例如,圖中SERVICE INSTANCE A訪問SERVICE REGISTRY獲取服務注冊信息,然后直接訪問SERVICE INSTANCE B
自理式服務發現實現比較簡單,因為這部分的功能一般通過統一的程序庫或者程序包提供給各個微服務調用,而不會每個微服務都自己來重復實現一遍;并且由于每個微服務都承擔了服務發現的功能,訪問壓力分散到了各個微服務節點,性能和可用性上不存在明顯的壓力和風險
2. 代理式
代理式結構如下:
代理式結構就是指微服務之間有一個負載均衡系統,由負載均衡系統來完成微服務之間的服務發現
代理式的方式看起來更加清晰,微服務本身的實現也簡單了很多,但實際上這個方案風險較大
第一個風險是可用性風險,一旦LOAD BALANCER系統故障,就會影響所有微服務之間的調用
第二個風險是性能風險,所有的微服務之間的調用流量都要經過LOAD BALANCER系統,性能壓力會隨著微服務數量和流量增加而不斷增加,最后成為性能瓶頸
因此LOAD BALANCER系統需要設計成集群的模式,但LOAD BALANCER集群的實現本身又增加了復雜性
不管是自理式還是代理式,服務發現的核心功能就是服務注冊表,注冊表記錄了所有的服務節點的配置和狀態,每個微服務啟動后都需要將自己的信息注冊到服務注冊表,然后由微服務或者LOAD BALANCER系統到服務注冊表查詢可用服務
服務路由
有了服務發現之后,微服務之間能夠方便地獲取相關配置信息,但具體進行某次調用請求時,我們還需要從所有符合條件的可用微服務節點中挑選出一個具體的節點發起請求,這就是服務路由需要完成的功能
服務路由和服務發現緊密相關,服務路由一般不會設計成一個獨立運行的系統,通常情況下是和服務發現放在一起實現的
對于自理式服務發現,服務路由是微服務內部實現的;對于代理式服務發現,服務路由是由LOAD BALANCER系統實現的
無論放在哪里實現,服務路由核心的功能就是路由算法。常見的路由算法有:隨機路由、輪詢路由、最小壓力路由、最小連接數路由等
服務容錯
系統拆分為微服務后,單個微服務故障的概率變小,故障影響的范圍也減少,但是微服務的節點數量大大增加
從整體上來看,系統中某個微服務出故障的概率會大大增加
微服務具有故障擴散的特點,如果不及時處理故障,故障擴散開來就會導致看起來系統中很多服務節點都故障了, 因此需要微服務能夠自動應對這種出錯場景,及時進行處理。否則,如果節點一故障就需要人工處理,投入人力大,處理速度慢;而一旦處理速度慢,則故障就很快擴散,所以我們需要服務容錯的能力
常見的服務容錯包括請求重試、流控和服務隔離
通常情況下,服務容錯會集成在服務發現和服務路由系統中
服務監控
系統拆分微服務后,節點數量大大增加,導致需要監控的機器、網絡、進程、接口調用數等控制對象的數量大大增加;同時,一旦發生故障,我們需要快速根據各類信息來定位故障。靠人力去完成是不現實的
例如,我們收到用戶投訴說業務有問題,如果此時采用人工的方式去搜集、分析信息,可能把幾十個節點的日志打開一遍就需要十幾分鐘了,因此需要服務監控系統來完成微服務節點的監控
作用
實施搜集信息并進行分析,避免故障后再來分析,減少了處理時間
服務監控可以在實時分析的基礎上進行預警,在問題萌芽的階段發覺并預警,降低了問題影響的范圍和時間
通常情況下,服務監控需要搜集分析大量的數據,因此建議做成獨立的系統,而不要集成到服務發現、API網關等系統中
服務跟蹤
服務監控可以做到微服務節點級的監控和信息收集,但如果我們需要跟蹤某一個請求在微服務中的完整路徑,服務監控是難以實現的。如果每個服務的完整請求鏈信息都實時發送給服務監控系統中,數據量會大到無法處理
服務監控和服務跟蹤的區別可以簡單概括為宏觀和微觀的區別。例如,A服務通過HTTP協議請求B服務10次,B通過HTTP返回JSON對象,服務監控會記錄請求次數、響應時間、響應錯誤碼、請求參數、返回的JOSN對象等信息
目前無論是分布式跟蹤還是微服務的服務跟蹤,絕大部分請求跟蹤的實現技術都基于Google的Dapper論文《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》
服務安全
系統拆分為微服務后,數據分散在各個微服務節點上
從系統連接的角度來說,任意微服務都可以訪問所有其他微服務節點
從業務的角度來說,部分敏感數據或者操作,只能部分微服務可以訪問,而不是所有的微服務都可以訪問,因此需要設計服務安全機制來保證業務和數據的安全性
服務安全主要分為三部分:接入安全、數據安全、傳輸安全
通常情況下,服務安全可以集成到配置中心系統中進行實現,即配置中心配置微服務的接入安全策略和數據安全策略,微服務節點從配置中心獲取這些配置信息,然后在處理具體的微服務調用請求時根據安全策略進行處理。
由于這些策略是通用的,一般會把策略封裝通用的庫提供給各個微服務調用。
基本架構如下:
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。