服務(wù)器又崩了?深度解析高可用架構(gòu)的挑戰(zhàn)和實(shí)踐
大家好,我是騰訊微服務(wù)平臺(tái)TSF 產(chǎn)品經(jīng)理劉閻,目前主要負(fù)責(zé)TSF高可用能力建設(shè)及演進(jìn)規(guī)劃工作,本次分享我會(huì)結(jié)合自己對(duì)微服務(wù)架構(gòu)的理解以及TSF在高可用能力建設(shè)上的最佳實(shí)踐與大家共同討論如何構(gòu)建高可用的微服務(wù)架構(gòu)。
微服務(wù)架構(gòu)挑戰(zhàn)
軟件架構(gòu)的演進(jìn)歷程
首先我們先來看下軟件架構(gòu)的演進(jìn)歷程:
單體架構(gòu):沒有復(fù)雜邏輯分層,前后代碼耦合,單個(gè)應(yīng)用可能與多個(gè)數(shù)據(jù)庫關(guān)聯(lián)
適用于:迭代頻率低,并發(fā)量小,業(yè)務(wù)邏輯簡單的應(yīng)用場景,目前單體架構(gòu)在政府、金融、工業(yè)領(lǐng)域仍有廣泛應(yīng)用。
SOA架構(gòu):按業(yè)務(wù)邏輯進(jìn)行服務(wù)拆分,服務(wù)間通過服務(wù)總線進(jìn)行服務(wù)管理及流量轉(zhuǎn)發(fā)
其主要問題在于:服務(wù)總線成為系統(tǒng)新的瓶頸,難以伴隨業(yè)務(wù)的不斷發(fā)展?jié)M足線性擴(kuò)容的要求。
微服務(wù)架構(gòu):服務(wù)架構(gòu)通過服務(wù)注冊中心實(shí)現(xiàn)服務(wù)注冊發(fā)現(xiàn),服務(wù)啟動(dòng)時(shí)將服務(wù)實(shí)例注冊到注冊中心,調(diào)用方在發(fā)起調(diào)用時(shí)通過注冊中心進(jìn)行服務(wù)尋址,直接與提供方進(jìn)行通信。理論上服務(wù)可以伴隨業(yè)務(wù)發(fā)展實(shí)現(xiàn)線性擴(kuò)展,不同服務(wù)之間可單獨(dú)迭代,實(shí)現(xiàn)敏捷開發(fā)。
服務(wù)網(wǎng)格:版本云原生k8s及容器技術(shù)發(fā)展,服務(wù)網(wǎng)格技術(shù)已趨于成熟,相較于傳統(tǒng)的微服務(wù)架構(gòu),服務(wù)網(wǎng)格通過sidercar模式進(jìn)行流量代理和服務(wù)注冊發(fā)現(xiàn),無需業(yè)務(wù)感知,輕松實(shí)現(xiàn)跨語言服務(wù)治理,幫助業(yè)務(wù)快速遷移,使業(yè)務(wù)應(yīng)用更加專注自身業(yè)務(wù)邏輯實(shí)現(xiàn)。
每種軟件架構(gòu)沒有嚴(yán)格意義上的好壞之分,用戶需要根據(jù)自身的業(yè)務(wù)特點(diǎn)進(jìn)行架構(gòu)選型。
微服務(wù)應(yīng)用常見問題
微服務(wù)架構(gòu)在滿足高并發(fā)、敏捷迭代的同時(shí),業(yè)務(wù)模塊數(shù)量成幾何數(shù)增長,給應(yīng)用運(yùn)維帶來了嚴(yán)峻挑戰(zhàn),微服務(wù)架構(gòu)相較于傳統(tǒng)單體架構(gòu),具有流量洪峰激增、模塊依賴復(fù)雜、故障定位難度大、故障恢復(fù)耗時(shí)長的特點(diǎn)。
- 流量激增:單體應(yīng)用拆分為微服務(wù)應(yīng)用后,原有的單一請求邏輯拆分為多個(gè)微服務(wù)應(yīng)用的組合業(yè)務(wù)邏輯,接口調(diào)用量成1:N的增長關(guān)系,面對(duì)流量洪峰,接口調(diào)用量激增。
- 模塊依賴復(fù)雜:原有的單體應(yīng)用僅存在單一進(jìn)程內(nèi)的業(yè)務(wù)邏輯組合,微服務(wù)應(yīng)用拆分為多個(gè)進(jìn)程,各模塊間的服務(wù)上下游依賴關(guān)系復(fù)雜,單個(gè)微服務(wù)或單個(gè)接口異常通常引發(fā)鏈?zhǔn)椒磻?yīng),造成服務(wù)雪崩。
- 故障定位難度大:單次請求異常需要依據(jù)各模塊的依賴關(guān)系分析整個(gè)調(diào)用鏈路定位故障原因,由于橫跨多個(gè)微服務(wù)應(yīng)用進(jìn)程的不同業(yè)務(wù)邏輯,故障定位難度陡增。
- 故障恢復(fù)耗時(shí)長:由于各微服務(wù)模塊依賴關(guān)系復(fù)雜,需要根據(jù)調(diào)用鏈準(zhǔn)確定位故障問題根源并進(jìn)行逐級(jí)恢復(fù),故障恢復(fù)及恢復(fù)后驗(yàn)證評(píng)價(jià)結(jié)果耗時(shí)長。
如何度量系統(tǒng)可用性指標(biāo)
管理學(xué)大師彼得德魯克曾說“你如果無法度量它,就無法管理它”(“It you can’t measure it, you can’t manage it”)。要想有效管理,就難以繞開度量的問題。
那如何度量分布式系統(tǒng)的可用性指標(biāo)呢,這里有一個(gè)簡單公式,可用性=平均故障間隔時(shí)間/平均故障間隔時(shí)間與平均故障恢復(fù)時(shí)間之和。
所謂平均故障間隔時(shí)間是指相鄰兩次故障之間的平均工作時(shí)間,也稱為平均故障間隔。平均修復(fù)時(shí)間是從出現(xiàn)故障到修復(fù)中間的這段時(shí)間。MTTR 越短表示易恢復(fù)性越好。
MTBF:即平均故障間隔時(shí)間,英文全稱是“Mean Time Between Failure”。是衡量一個(gè)產(chǎn)品(尤其是電器產(chǎn)品)的可靠性指標(biāo)。單位為“小時(shí)”。
MTTR:全稱是 Mean Time To Repair,即平均修復(fù)時(shí)間。是指可修復(fù)產(chǎn)品的平均修復(fù)時(shí)間,就是從出現(xiàn)故障到修復(fù)中間的這段時(shí)間。MTTR 越短表示易恢復(fù)性越好。
高可用架構(gòu)設(shè)計(jì)的道、法、術(shù)
那如何設(shè)計(jì)高可用的微服務(wù)架構(gòu)呢?接下來我將分別從道、法、術(shù)三個(gè)層面講高可用微服務(wù)架構(gòu)設(shè)計(jì)的基本原理、架構(gòu)設(shè)計(jì)原則、以及高可用架構(gòu)常用的解決方法。
道:從CAP到BASE
CAP 理論:在一個(gè)分布式系統(tǒng)中, 一致性(C:Consistency)、可用性(A:Availability) 和 分區(qū)容忍性(P:Partition Tolerance),最多只能同時(shí)滿足其中兩項(xiàng)。其中分區(qū)容忍性(P:Partition Tolerance)是復(fù)雜網(wǎng)絡(luò)環(huán)境下的必須要素,因此分布式系統(tǒng)的架構(gòu)設(shè)計(jì)需要在一致性和可用性之間進(jìn)行取舍。就誕生了諸如:Paxos 算法 和 Raft 算法強(qiáng)一致性共識(shí)算法,以及2階段提交,3階段提交的最終一致性算法。
BASE 理論:BASE是對(duì) CAP 中一致性和可用性權(quán)衡的結(jié)果,它的理論的核心思想是:即使無法做到強(qiáng)一致性,但每個(gè)應(yīng)用都可以根據(jù)自身業(yè)務(wù)特點(diǎn),采用適當(dāng)?shù)姆绞絹硎瓜到y(tǒng)達(dá)到最終一致性。
法:微服務(wù)高可用架構(gòu)設(shè)計(jì)原則
結(jié)合我對(duì)微服務(wù)高可用架構(gòu)的理解,總結(jié)出以下6點(diǎn)高可用架構(gòu)設(shè)計(jì)的原則,分別是服務(wù)無狀態(tài)、異步解耦、分區(qū)容錯(cuò)、故障隔離、快速恢復(fù)、最終一致性:
服務(wù)無狀態(tài):服務(wù)應(yīng)用進(jìn)行無狀態(tài)設(shè)計(jì),將服務(wù)應(yīng)用的狀態(tài)數(shù)據(jù)通過緩存、數(shù)據(jù)庫進(jìn)行集中存儲(chǔ),通過nginx或網(wǎng)關(guān)進(jìn)行負(fù)載均衡實(shí)現(xiàn)水平擴(kuò)展。
異步解耦:各服務(wù)模塊通過發(fā)布訂閱、事件驅(qū)動(dòng)方式進(jìn)行異步解耦,單次請求調(diào)用通過異步回調(diào)方式快速響應(yīng),將通知事件與處理結(jié)果分離,避免異常雪崩。
分區(qū)容錯(cuò):基于指定的業(yè)務(wù)規(guī)則實(shí)現(xiàn)業(yè)務(wù)分流路由,將流量分發(fā)至多個(gè)可用區(qū),不同可用區(qū)通過數(shù)據(jù)同步、多備份機(jī)制保障數(shù)據(jù)一致性。
故障隔離:單一進(jìn)程、單一接口、單一服務(wù)通過熔斷、降級(jí)機(jī)制實(shí)現(xiàn)故障隔離,避免系統(tǒng)關(guān)聯(lián)異常,引發(fā)雪崩效應(yīng)。
快速恢復(fù):通過流量切分,版本管理、應(yīng)用回滾機(jī)制實(shí)現(xiàn)應(yīng)用快速回退至健康版本,快速恢復(fù)應(yīng)用。
最終一致性:通過多數(shù)據(jù)源雙寫、數(shù)據(jù)稽核、數(shù)據(jù)修復(fù)實(shí)現(xiàn)數(shù)據(jù)跨可用區(qū)數(shù)據(jù)最終一致性。
術(shù):高可用常用手段
分區(qū)容錯(cuò):
異地容災(zāi)是高可用架構(gòu)典型的應(yīng)用場景,通過將不同地域的數(shù)據(jù)中心構(gòu)建多套應(yīng)用服務(wù),當(dāng)單一地域服務(wù)宕機(jī)時(shí)可快速通過流量切換災(zāi)備中心保障業(yè)務(wù)持續(xù)、穩(wěn)定。異地容災(zāi)按保障級(jí)別不同分為,多可用區(qū)、同城冷備、同城雙活、異地冷備、兩地三中心五個(gè)級(jí)別,其保障級(jí)別、應(yīng)用成本、恢復(fù)延遲都呈遞增趨勢。
異步解耦:
在微服務(wù)應(yīng)用中通過引入消息中間件將上游組合服務(wù)對(duì)下游多個(gè)微服務(wù)的同步調(diào)用進(jìn)行異步解耦,基于消息的可靠投遞能力快速響應(yīng)用戶請求,能夠大幅提升服務(wù)并發(fā)訪問性能及用戶體驗(yàn),并通過數(shù)據(jù)補(bǔ)償手段保障數(shù)據(jù)最終一致性。
服務(wù)限流:
由于 API 接口無法控制調(diào)用方的行為,因此當(dāng)遇到瞬時(shí)請求量激增時(shí),會(huì)導(dǎo)致接口占用過多服務(wù)器資源,使得其他請求響應(yīng)速度降低或是超時(shí),嚴(yán)重導(dǎo)致服務(wù)器宕機(jī)。服務(wù)限流主要是保護(hù)服務(wù)節(jié)點(diǎn)或者數(shù)據(jù)節(jié)點(diǎn),防止瞬時(shí)流量過大造成服務(wù)和數(shù)據(jù)崩潰,導(dǎo)致服務(wù)不可用。
局部限流:基于簡單計(jì)數(shù)、令牌桶、漏斗算法在單個(gè)節(jié)點(diǎn)內(nèi)的限流,僅能限制傳入此節(jié)點(diǎn)的請求,無需引入中間件,通過局部限流達(dá)到全局限流的目的,同時(shí)避免實(shí)例級(jí)別單一接口訪問量激增問題
全局限流:基于簡單計(jì)數(shù)、令牌桶算法,通過引入中間件如redis,針對(duì)整個(gè)集群流量進(jìn)行全局控制。
服務(wù)熔斷:
服務(wù)熔斷是應(yīng)對(duì)服務(wù)異常,實(shí)現(xiàn)服務(wù)容錯(cuò),避免服務(wù)雪崩的有效手段。
從下圖中可以看出,當(dāng)網(wǎng)關(guān)入口服務(wù)請求下游多個(gè)服務(wù)接口,當(dāng)服務(wù)C接口異常將導(dǎo)致入口服務(wù)流量的不可用,服務(wù)A、服務(wù)E請求則白白占用。
從下圖中可以看出,當(dāng)網(wǎng)關(guān)入口的服務(wù)請求下游的單一服務(wù)接口,當(dāng)服務(wù)B接口異常將導(dǎo)致入口請求夯住,占用網(wǎng)關(guān)請求資源,導(dǎo)致整體業(yè)務(wù)異常。
針對(duì)以上兩種異常場景,通過在服務(wù)調(diào)用時(shí)配置熔斷策略能夠快速失敗,直接反饋上游業(yè)務(wù)異常結(jié)果,避免請求線程夯死及服務(wù)雪崩。
降級(jí)容錯(cuò):
服務(wù)降級(jí)是在服務(wù)器壓力陡增的情況下,利用有限資源,根據(jù)當(dāng)前業(yè)務(wù)情況,關(guān)閉某些服務(wù)接口或者頁面,以此釋放服務(wù)器資源以保證核心服務(wù)的正常運(yùn)行。
TSF高可用最佳實(shí)踐
TSF微服務(wù)平臺(tái)針對(duì)業(yè)務(wù)流量激增、服務(wù)異常容錯(cuò)等問題提供架構(gòu)容災(zāi)、灰度發(fā)布、服務(wù)容錯(cuò)兜底、實(shí)例優(yōu)雅啟停、應(yīng)用性能管理的一體化高可用服務(wù)架構(gòu)。突出立體化、自動(dòng)化、可視化的優(yōu)勢,提供端到端的應(yīng)用性能監(jiān)控,多維度可視化的運(yùn)行監(jiān)控?cái)?shù)據(jù)聚合分析,實(shí)現(xiàn)故障自動(dòng)感知,自動(dòng)處理,快速恢復(fù)故障業(yè)務(wù),保障系統(tǒng)的穩(wěn)定高效運(yùn)行。
單元化架構(gòu)部署
單元化架構(gòu)是一種高級(jí)的高可用架構(gòu)設(shè)計(jì)模式,通過對(duì)核心業(yè)務(wù)數(shù)據(jù)分片,應(yīng)用服務(wù)無狀態(tài)設(shè)計(jì)將相同領(lǐng)域的業(yè)務(wù)服務(wù)劃分為一個(gè)個(gè)獨(dú)立的部署單元,單元內(nèi)整體業(yè)務(wù)閉環(huán)。通過單元化部署架構(gòu)能夠有效滿足彈性伸縮,故障隔離,異地容災(zāi)等高可用建設(shè)要求。此外基于單元化部署可以實(shí)現(xiàn)以部署單元為基準(zhǔn),構(gòu)建靈活的發(fā)布策略。
單元化架構(gòu)產(chǎn)品能力:
- 網(wǎng)關(guān)業(yè)務(wù)單元路由標(biāo)簽
- 支持跨單元橫向調(diào)用
- 單元內(nèi)服務(wù)容錯(cuò)兜底
彈性伸縮
通過配置動(dòng)態(tài)伸縮規(guī)則,TSF中控服務(wù)基于agent上報(bào)的監(jiān)控?cái)?shù)據(jù)實(shí)現(xiàn)實(shí)時(shí)統(tǒng)計(jì),滿足流量激增自動(dòng)擴(kuò)容或流量低峰自動(dòng)縮容能力,有效保障服務(wù)高效穩(wěn)定及資源利用率提升。
全鏈路灰度發(fā)布
灰度發(fā)布是將具有一定特征或者比例的流量分配到需要被驗(yàn)證的版本中,用來觀察新的驗(yàn)證版本的線上運(yùn)行狀態(tài)。相比全量上線,灰度發(fā)布是更加謹(jǐn)慎的發(fā)布形式。當(dāng)線上調(diào)用鏈路較為復(fù)雜時(shí),全鏈路灰度發(fā)布可以將線上的各個(gè)服務(wù)隔離出一個(gè)單獨(dú)的運(yùn)行環(huán)境。
全鏈路灰度產(chǎn)品能力:
- 基于業(yè)務(wù)級(jí)別的全鏈路灰度發(fā)布能力
- 支持按照業(yè)務(wù)級(jí)別請求參數(shù)對(duì)流量進(jìn)行劃撥
- 泳道間流量隔離
優(yōu)雅啟停
在應(yīng)用滾動(dòng)發(fā)布過程中,可以通過調(diào)整部署組滾動(dòng)發(fā)布更新策略達(dá)到服務(wù)優(yōu)雅下線,降低發(fā)布過程中業(yè)務(wù)中斷影響。
這里簡單介紹優(yōu)雅下線的簡單流程
- 下線實(shí)例在注冊中心進(jìn)行反注冊,注銷該實(shí)例注冊信息;
- 注冊中心節(jié)點(diǎn)訂閱更新周期為15s,調(diào)用方在感知注冊中心實(shí)例變更后,更新本地緩存服務(wù)地址,不再將流量路由到下線實(shí)例,期間保障業(yè)務(wù)無中斷;
- 下線實(shí)例等待30s(2個(gè)心跳周期)后進(jìn)行實(shí)際下線操作;
優(yōu)雅啟停產(chǎn)品能力:
- 支持容器、虛機(jī)部署方式
- 實(shí)例反注冊下線事件詳情
- 實(shí)例啟動(dòng)就緒檢測
服務(wù)限流
TSF 限流基于監(jiān)控服務(wù)流量的 QPS 指標(biāo),當(dāng)達(dá)到指定的閾值時(shí)進(jìn)行流量控制,避免被瞬時(shí)高峰流量沖垮,從而確保服務(wù)的高可用。支持在網(wǎng)關(guān)配置全局限流策略保障入口服務(wù)流量穩(wěn)定支持針對(duì)單一服務(wù)配置局部限流策略保障當(dāng)前服務(wù)流量穩(wěn)定,同時(shí)提供靈活的限流規(guī)則配置及動(dòng)態(tài)生效,提供可視化的限流操作及監(jiān)控?cái)?shù)據(jù)展示。
服務(wù)熔斷
TSF服務(wù)熔斷能力支持服務(wù)、實(shí)例、API多維度的熔斷隔離級(jí)別,提供控制臺(tái)可視化配置及熔斷事件展示,滿足熔斷配置熱生效需求。
熔斷器狀態(tài)轉(zhuǎn)換:
熔斷器開始處于closed狀態(tài),一旦檢測到錯(cuò)誤(或慢響應(yīng))達(dá)到一定閾值,便轉(zhuǎn)為open狀態(tài),此時(shí)不再調(diào)用下游目標(biāo)服務(wù)。
一段時(shí)間后轉(zhuǎn)化為half open狀態(tài),嘗試放行一部分請求到下游服務(wù)。
一旦檢測到響應(yīng)成功,回歸到closed狀態(tài),也即恢復(fù)服務(wù);否則回到open狀態(tài)。
健康檢查與注冊中心聯(lián)動(dòng)流程
健康檢查分為存活檢查及就緒檢查;存活檢查主要作用是確定進(jìn)程存活狀態(tài),判斷是否需要進(jìn)行實(shí)例重啟。就緒檢查主要作用是確定服務(wù)實(shí)例能否支持對(duì)外服務(wù),將健康檢查結(jié)果與注冊中心狀態(tài)聯(lián)動(dòng)避免流量接入異常節(jié)點(diǎn)。
健康檢查與注冊中心聯(lián)動(dòng)流程
1.就緒檢查,檢查實(shí)例狀態(tài)是否ready
2.如果就緒檢查ready則更新實(shí)例注冊狀態(tài)為passing,反之則檢查狀態(tài)為cirtical
3.監(jiān)聽注冊中心服務(wù)提供方實(shí)例狀態(tài)變更
4.存在狀態(tài)變更更新緩存及本地文件
5.發(fā)起服務(wù)調(diào)用
- 健康檢查產(chǎn)品能力:
- 存活檢查
- 就緒檢查
- 多種探測方式:http,tcp,執(zhí)行命令
- 支持虛機(jī)&容器部署
應(yīng)用性能管理能力
最后我們從一個(gè)問題排查流程全局展示tsf應(yīng)用性能管理能力:
- 用戶收到監(jiān)控平臺(tái)發(fā)送的告警信息,確定異?;拘畔?。
- 通過服務(wù)依賴拓?fù)浯_定異常服務(wù)的上下游依賴關(guān)系,進(jìn)行全局視圖分析。
- 接下來可以服務(wù)接口調(diào)用情況確定是全局接口異?;蚴菃我唤涌诋惓!?/li>
- 如果是全局接口異常說明服務(wù)提供方服務(wù)實(shí)例存在異常問題,找到對(duì)應(yīng)的異常實(shí)例通過日志檢索或JVM監(jiān)控分析排查具體問題;如果是單一接口異常說明提供方接口邏輯處理,通過日志檢索可排查具體問題。
- 當(dāng)然也可以在全局視圖分析后通過對(duì)直接服務(wù)進(jìn)行調(diào)用鏈分析排查單筆請求的調(diào)用鏈路,通過調(diào)用鏈與日志聯(lián)動(dòng)排查具體異常。