【穩定性】穩定性建設之依賴設計

京东云开发者發表於2024-03-21

背景
隨著分散式微服務的發展,一個普通的應用可能會依賴於許多其他服務,這給系統的限流降級、最佳化改造等操作帶來了困難。在沒有明確強弱依賴關係的情況下,我們很難有效地進行這些操作。為了解決這個問題,強弱依賴治理成為了一種科學的手段。透過強弱依賴治理,我們可以持續穩定地獲取應用間的依賴關係、流量以及強弱等資料。這樣,我們可以提前發現由於依賴問題可能導致的系統穩定性故障。

一、依賴概念
依賴原則是去除依賴、弱化依賴、控制依賴。多一個依賴多一分風險。能不依賴則不依賴,能非同步弱依賴不要同步強依賴。

(1)最強依賴
當所依賴的服務不可用時,服務不可用,且造成系統崩潰。對於所有的依賴,不建議最強依賴。

(2)強依賴
假定服務 A 依賴於服務 B,服務 B 出現故障不可用時,服務 A 也不可用,通常服務 A 會返回錯誤資訊,且當所依賴的 B 服務恢復後自動恢復,我們稱這種依賴為強依賴。服務只可強依賴於同等級或高等級的服務與資源。

案例:商詳結算下單服務對於庫存服務的依賴就屬於強依賴,下單時必須校驗是否有庫存。

(3)弱依賴
假定服務 A 依賴於服務 B,服務 B 出現故障不可用時,服務 A 仍然可用,通常服務 A 會返回正確資訊,只是與服務 B 相關的資訊會不返回或者做預設處理,損失一些次級功能,我們稱這種依賴為弱依賴。

案例:下單服務對於話術的依賴就屬於弱依賴。

(4)最弱依賴
當所依賴的服務不可用時,服務繼續可用,無任何功能損失。在成本可控情況下,推薦採用最弱依賴的方式。

案例:商詳評論,在大促高峰期期如有必要是可以進行降級的。



二、依賴分類
分散式系統下的各資源依賴,按型別和層次提煉出來會有如下幾種分類。

(1)業務域依賴原則
建議上層業務域可以依賴下層業務域,整體的依賴原則受到系統依賴原則的控制,必須首先遵守應用系統之間的依賴原則,而下層業務域不允許依賴上層業務域。

核心是輸出系統核心功能場景的流程圖、時序圖、架構圖,用例圖,領域模型等,需要結合業務來進行梳理。

(2)系統啟動依賴
系統啟動只允許依賴資料庫、應用伺服器本地資源(如本地檔案)、公共儲存,不允許有其它基礎技術服務、內部服務或外部服務依賴。消除啟動依賴可以支援當發生大規模故障後的快速恢復。

案例:OPS-Review 會上很多團隊系統啟動需要載入快取,透過獲取 Redis 讀取資料到本地快取,這需要注意一點在大促期間如大批次擴容,需要考慮 Redis 同時的容量規劃

(3)基礎技術服務依賴
基礎軟體依賴主要包括訊息中心以及資料快取依賴,同時還應考慮系統軟體及其第三方包依賴,應用系統若無特殊情況不應依賴底層作業系統或 JVM 特定版本。

•快取設計:快取過期時間是多少?對應 key 範圍,set 入口等
•訊息依賴:系統釋出了哪些訊息,訂閱了哪些訊息,什麼時機傳送的,核心的消費者有哪些,訊息是否需要開並行,訊息下游依賴是什麼?如果出現問題對自身系統和下游的核心影響是什麼?
•定時任務:有哪些定時任務,是什麼業務需要?定時任務執行的時間,是否會跟雙 11 大促高峰期衝突?
(4)資料庫依賴原則
把資料庫按照資料等級進行分級,不同等級的資料庫的資料保護和業務連續性保證都不一樣。高優先順序應用系統不能夠強依賴於次優先順序的資料庫,以此類推各級應用系統不允許強依賴低於自己等級的資料庫服務。

資料庫依賴(強弱依賴、依賴權重)可能很多簡單系統都只有一個資料庫,資料庫掛了整個系統就掛了,實際上很多重要的複雜系統都會同時具有多個資料來源,將核心業務從資料來源層面隔離開,哪怕有天資料庫掛了,也不是業務全掛。核心是輸出業務與資料庫依賴關係,資料庫的部署架構,如果能輸出慢 sql 治理方案,畫出資料庫表 ER 圖。

(5)部署依賴原則
應用系統自身的網路的依賴需求:包括跨機房的網路依賴、外網訪問、防火牆等。原則上日常態不建議有跨機房的服務呼叫網路需求 (特殊情況如資料複製、容災等除外),實現單機房內自閉環。匯天機房呼叫匯天機房,廊坊呼叫下游的廊坊機房,宿遷呼叫下游的宿遷機房

(6)對外 API&MQ 與訪問量依賴原則
核心是根據訪問模式和訪問量可以推算出未來的訪問量,並進行容量分析和規劃。

(7)硬體依賴原則
硬體這個方面,就交給硬體運維吧,專業的事情交給專業的人來做。

三、強弱依賴治理
(1)治理目標
透過對核心鏈路內外部服務依賴治理,我們的目標是實現以下兩個關鍵目標:

1.非核心業務故障不影響核心業務:透過最佳化服務依賴關係,確保非核心業務的故障不會對核心業務造成影響。這可以透過輸出服務、應用及場景的依賴關係來實現,包括強弱依賴關係的明確劃分。同時,我們會定期進行全量強弱依賴驗證,以確保核心服務、應用及場景相關上下游依賴的強弱合理清晰。
2.提高系統的穩定性:透過弱依賴出現各類異常(包括但不限於超時、失敗等)場景時的容錯邏輯和應急預案,有效避免弱依賴故障對核心業務的影響。
為了達到以上目標,我們將採取以下措施:

1.輸出應用及 API 場景的依賴關係:透過對系統進行全面的分析,我們將輸出完整的服務、應用及場景的依賴關係圖。這將幫助我們瞭解各個元件之間的關係,並確定強弱依賴關係。
2.弱依賴容錯邏輯和應急預案:針對弱依賴出現的各類異常情況,我們將制定相應的容錯邏輯和應急預案。這些預案將經過驗證,以確保其能有效避免弱依賴故障對核心業務的影響。
附:依賴關係和服務可用率關係圖






(2)工具掃描
分析服務實現流程中所依賴的所有應用系統(以及這些系統提供的服務)。對一個應用系統而言,將它提供的每一個服務所依賴的應用系統彙總起來,可以構成應用依賴總體結構圖。

2.1)Pfinder 應用拓撲圖
可看出應用的上游呼叫方和下游依賴方列表,可按 TP99、呼叫量維度排序。

2.2)API 介面的鏈路跟蹤環節
透過 Pfinder 的呼叫鏈跟蹤,可梳理對應的依賴關係以及對應的耗時統計:

(3)人工梳理
在前期,我們透過投入相當人力,透過程式碼走讀的形式將用車核心鏈路上的所有依賴及依賴強弱進行梳理。對每一個依賴,需要識別該依賴的以下屬性:

依賴強弱:強依賴是指必須的依賴,弱依賴是指可選的依賴;

同步或非同步:同步表示需要等待返回,非同步指呼叫發生後無需等待立即返回;比如 Promise 傳送全程跟蹤 MQ 原先是同步傳送 MQ(強依賴)改成非同步 (弱依賴) 傳送方式。

依賴權重:一次服務過程中依賴的次數,即訪問的次數。

針對具體的服務型別,需要針對性地開展依賴分析,如:Redis 依賴:服務實現流程中所依賴的所有快取資料,將它提供的每一個服務所依賴的快取資料彙總起來,可以構成該應用對 Redis 的依賴總體結構圖。

3.1)JSF-API 介面依賴梳理
案例:Promsie 提供了 80+JSF 介面,針對這些介面進行了依賴關係的梳理,把依賴關係的 UMP 打點統一採集點到一個 URL,並且整理為 joyspace 文件。這樣也是為了方便快速定位 TP99 毛刺高是哪個依賴,然後快速採取對應的應急預案。

3.2)UMP 採集點突出依賴關係
UMP 打點目前是支援打點採集點比對功能,把介面的下游打點資訊全鏈路進行比對,可快速的定位到 tp99 等耗時環節,提高了日常的值班效率尤其對於大促爭分奪秒來說更是關鍵。

透過人工梳理發現,比如 Promise 的獲取下傳時效介面核心業務鏈路只有依賴 JIMDB 配置資料時效、產能狀態介面、GIS 經緯度獲取圍欄 ID、GIS 詳細地址獲取圍欄 ID、到家門店時效、傳送時效全程跟蹤 MQ。

上圖 Promise 介面經過梳理後發現其中只有 JIMDB、到家門店時效是強依賴。GIS 獲取圍欄 ID(可降級到四級地址時效)、全程跟蹤 MQ 是弱依賴

(4) 降級時機
如果弱依賴服務發生問題,則降級的觸發條件可分為主動降級和被動降級;

•主動降級:一般在大型活動時產生流量尖峰,系統無法支撐,提前對非核心的業務進行了降級處理;
•被動降級:一般是在發生故障時自動觸發預設的降級策略。
總結:
強弱依賴治理的實施需要以下幾個步驟:

1.確定依賴關係:首先,我們需要明確應用之間的依賴關係。這可以透過分析程式碼、配置檔案等方式來實現。只有瞭解了應用之間的依賴關係,我們才能進行後續的治理工作。
2.分析依賴資料:接下來,我們需要收集應用間的依賴關係、流量以及強弱等資料。這可以透過監控工具、日誌分析等方式來實現。透過收集這些資料,我們可以更好地瞭解系統的執行情況,發現潛在的依賴問題,並預測可能出現的故障。這樣,我們可以及時採取措施,為後續的治理工作提供依據。
3.制定最佳化方案:根據資料分析的結果,我們可以制定相應的最佳化方案。這可能包括調整應用間的依賴關係、最佳化流量分配等措施。透過實施這些最佳化方案,我們可以提升系統的穩定性和效能。
4.持續改進:強弱依賴治理是一個持續的過程。我們需要不斷地收集、分析和最佳化資料,以推動系統穩定性的提升。同時,我們還需要及時響應使用者反饋和需求變化,不斷改進我們的治理策略。
總之,強弱依賴治理是一種科學的手段,可以幫助我們應對分散式微服務的複雜性。透過持續穩定地獲取應用間的依賴關係、流量以及強弱等資料,我們可以提前發現潛在的故障,避免依賴故障對使用者體驗的影響,並積累資料持續推進系統穩定性的提升。



參考:信通院穩定性建設指南

相關文章