作者 | 魏磊 心澎 陳彤
CDN已經(jīng)成為互聯(lián)網(wǎng)重要的基建之一,越來越多的網(wǎng)絡(luò)服務(wù)離不開CDN,它的穩(wěn)定性也直接影響到業(yè)務(wù)的可用性。CDN的容災(zāi)一直由美團(tuán)的SRE團(tuán)隊(duì)在負(fù)責(zé),在端側(cè)鮮有方案和實(shí)踐。
本文結(jié)合美團(tuán)外賣業(yè)務(wù)中的具體實(shí)踐,介紹了一種在端側(cè)感知CDN可用性狀況并進(jìn)行自動(dòng)容災(zāi)切換的方案,通過該方案可有效降低業(yè)務(wù)對(duì)CDN異常的敏感,提高業(yè)務(wù)的可用性,同時(shí)降低CDN運(yùn)維壓力。希望本方案能夠?qū)Ρ籆DN問題所困擾的同學(xué)有所幫助或者啟發(fā)。
1. 前言
作為業(yè)務(wù)研發(fā),你是否遇到過因?yàn)?CDN 問題導(dǎo)致的業(yè)務(wù)圖片加載失敗,頁面打開緩慢,頁面布局錯(cuò)亂或者頁面白屏?你是否又遇到過某些區(qū)域 CDN 域名異常導(dǎo)致業(yè)務(wù)停擺,客訴不斷,此時(shí)的你一臉茫然,不知所措?作為 CDN 運(yùn)維,你是否常常被業(yè)務(wù)方反饋的各種 CDN 問題搞得焦頭爛額,一邊頂著各種催促和壓力尋求解決方案,一邊抱怨著服務(wù)商的不靠譜?今天,我們主要介紹一下美團(tuán)外賣技術(shù)團(tuán)隊(duì)端側(cè) CDN 的容災(zāi)方案,經(jīng)過實(shí)踐,我們發(fā)現(xiàn)該產(chǎn)品能有效減少運(yùn)維及業(yè)務(wù)開發(fā)同學(xué)的焦慮,希望我們的這些經(jīng)驗(yàn)也能夠幫助到更多的技術(shù)團(tuán)隊(duì)。
2. 背景
CDN 因能夠有效解決因分布、帶寬、服務(wù)器性能帶來的網(wǎng)絡(luò)訪問延遲等問題,已經(jīng)成為互聯(lián)網(wǎng)不可或缺的一部分,也是前端業(yè)務(wù)嚴(yán)重依賴的服務(wù)之一。在實(shí)際業(yè)務(wù)生產(chǎn)中,我們通常會(huì)將大量的靜態(tài)資源如 JS 腳本、CSS 資源、圖片、視頻、音頻等托管至 CDN 服務(wù),以享受其邊緣節(jié)點(diǎn)緩存對(duì)靜態(tài)資源的加速。但是在享用 CDN 服務(wù)帶來更好體驗(yàn)的同時(shí),也經(jīng)常會(huì)被 CDN 故障所影響。比如因 CDN 邊緣節(jié)點(diǎn)異常,CDN 域名封禁等導(dǎo)致頁面白屏、排版錯(cuò)亂、圖片加載失敗。每一次的 CDN 故障,業(yè)務(wù)方往往束手無策,只能寄希望于 CDN 團(tuán)隊(duì)。而 CDN 的監(jiān)控與問題排查,對(duì) SRE 也是巨大的難題和挑戰(zhàn)。一方面,由于 CDN 節(jié)點(diǎn)的分布廣泛,邊緣節(jié)點(diǎn)的監(jiān)控就異常困難。另一方面,各業(yè)務(wù)匯聚得到的 CDN 監(jiān)控大盤,極大程度上隱匿了細(xì)節(jié)。小流量業(yè)務(wù)、定點(diǎn)區(qū)域的 CDN 異常往往會(huì)被淹沒。SRE 團(tuán)隊(duì)也做了很多努力,設(shè)計(jì)了多種方案來降低 CDN 異常對(duì)業(yè)務(wù)的影響,也取得了一定的效果,但始終有幾個(gè)問題無法很好解決:
- 時(shí)效性:當(dāng) CDN 出現(xiàn)問題時(shí),SRE 會(huì)手動(dòng)進(jìn)行 CDN 切換,因?yàn)樾枰藶椴僮?,響?yīng)時(shí)長(zhǎng)就很難保證。另外,切換后故障恢復(fù)時(shí)間也無法準(zhǔn)確保障。
- 有效性:切換至備份 CDN 后,備份 CDN 的可用性無法驗(yàn)證,另外因?yàn)?Local DNS 緩存,無法解決域名劫持和跨網(wǎng)訪問等問題。
- 精準(zhǔn)性:CDN 的切換都是大范圍的變更,無法針對(duì)某一區(qū)域或者某一項(xiàng)目單獨(dú)進(jìn)行。
- 風(fēng)險(xiǎn)性:切換至備份 CDN 之后可能會(huì)導(dǎo)致回源,流量劇增拖垮源站,從而引發(fā)更大的風(fēng)險(xiǎn)。
當(dāng)前,美團(tuán)外賣業(yè)務(wù)每天服務(wù)上億人次,即使再小的問題在巨大的流量面前,也會(huì)被放大成大問題。外賣的動(dòng)態(tài)化架構(gòu),70%的業(yè)務(wù)資源都依賴于 CDN,所以 CDN 的可用性嚴(yán)重影響著外賣業(yè)務(wù)。如何更有效的進(jìn)行 CDN 容災(zāi),降低 CDN 異常對(duì)業(yè)務(wù)的影響,是我們不斷思考的問題。既然以上問題 SRE 側(cè)無法完美地解決,端側(cè)是不是可以進(jìn)行一些嘗試呢?比如將 CDN 容災(zāi)前置到終端側(cè)。不死鳥(Phoenix) 就是在這樣的設(shè)想下,通過前端能力建設(shè),不斷實(shí)踐和完善的一套端側(cè) CDN 容災(zāi)方案。該方案不僅能夠有效降低 CDN 異常對(duì)業(yè)務(wù)的影響,還能提高 CDN 資源加載成功率,現(xiàn)已服務(wù)整個(gè)美團(tuán)多個(gè)業(yè)務(wù)和 App。
3. 目標(biāo)與場(chǎng)景
3.1 核心目標(biāo)
為降低 CDN 異常對(duì)業(yè)務(wù)的影響,提高業(yè)務(wù)可用性,同時(shí)降低 SRE 同學(xué)在 CDN 運(yùn)維方面的壓力,在方案設(shè)計(jì)之初,我們確定了以下目標(biāo):
- 端側(cè) CDN 域名自動(dòng)切換:在 CDN 異常時(shí),端側(cè)第一時(shí)間感知并自動(dòng)切換 CDN 域名進(jìn)行加載重試,減少對(duì)人為操作的依賴。
- CDN 域名隔離:CDN 域名與服務(wù)廠商在區(qū)域維度實(shí)現(xiàn)服務(wù)隔離且服務(wù)等效,保證 CDN 切換重試的有效性。
- 更精準(zhǔn)有效的 CDN 監(jiān)控:建設(shè)更細(xì)粒度的 CDN 監(jiān)控,能夠按照項(xiàng)目維度實(shí)時(shí)監(jiān)控 CDN 可用性,解決 SRE CDN 監(jiān)控粒度不足,告警滯后等問題。并根據(jù)容災(zāi)監(jiān)控對(duì) CDN 容災(zāi)策略實(shí)施動(dòng)態(tài)調(diào)整,減少 SRE 切換 CDN 的頻率。
- 域名持續(xù)熱備:保證每個(gè) CDN 域名的持續(xù)預(yù)熱,避免流量切換時(shí)導(dǎo)致回源。
3.2 適用場(chǎng)景
適用所有依賴 CDN ,希望降低 CDN 異常對(duì)業(yè)務(wù)影響的端側(cè)場(chǎng)景,包括 Web、SSR Web、Native 等技術(shù)場(chǎng)景。
4. Phoenix 方案
一直以來,CDN 的穩(wěn)定性是由 SRE 來保障,容災(zāi)措施也一直在 SRE 側(cè)進(jìn)行,但僅僅依靠鏈路層面上的保障,很難處理局部問題和實(shí)現(xiàn)快速止損。用戶終端作為業(yè)務(wù)的最終投放載體,對(duì)資源加載有著天然的獨(dú)立性和敏感性。如果將 CDN 容災(zāi)前置到終端側(cè),無論從時(shí)效性,精準(zhǔn)性,都是 SRE 側(cè)無法比擬的。在端側(cè)進(jìn)行容災(zāi),就需要感知 CDN 的可用性,然后實(shí)現(xiàn)端側(cè)自動(dòng)切換的能力。我們調(diào)研整個(gè)前端領(lǐng)域,并未發(fā)現(xiàn)業(yè)內(nèi)在端側(cè) CDN 容災(zāi)方面有所實(shí)踐和輸出,所以整個(gè)方案的實(shí)現(xiàn)是從無到有的一個(gè)過程。
4.1 總體設(shè)計(jì)
圖 1
Phoenix 端側(cè) CDN 容災(zāi)方案主要由五部分組成:
- 端側(cè)容災(zāi) SDK:負(fù)責(zé)端側(cè)資源加載感知,CDN 切換重試,監(jiān)控上報(bào)。
- 動(dòng)態(tài)計(jì)算服務(wù):根據(jù)端側(cè) SDK 上報(bào)數(shù)據(jù),對(duì)多組等效域名按照城市、項(xiàng)目、時(shí)段等維度定時(shí)輪詢計(jì)算域名可用性,動(dòng)態(tài)調(diào)整流量至最優(yōu) CDN。同時(shí)也是對(duì) CDN 可用性的日常巡檢。
- 容災(zāi)監(jiān)控平臺(tái):從項(xiàng)目維度和大盤維度提供 CDN 可用性監(jiān)控和告警,為問題排查提供詳細(xì)信息。
- CDN 服務(wù):提供完善的 CDN 鏈路服務(wù),在架構(gòu)上實(shí)現(xiàn)域名隔離,并為業(yè)務(wù)方提供等效域名服務(wù),保證端側(cè)容災(zāi)的有效性。等效域名,就是能夠通過相同路徑訪問到同一資源的域名,比如:cdn1.meituan.net/src/js/test.js 和 cdn2.meituan.net/src/js/test.js 能夠返回相同內(nèi)容,則 cdn1.meituan.net 和 cdn2.meituan.net 互為等效域名。
- 容災(zāi)配置平臺(tái):對(duì)項(xiàng)目容災(zāi)域名進(jìn)行配置管理,監(jiān)控上報(bào)策略管理,并提供 CDN 流量人工干預(yù)等措施。
4.2 容災(zāi)流程設(shè)計(jì)
為保證各個(gè)端側(cè)容災(zāi)效果和監(jiān)控指標(biāo)的一致性,我們?cè)O(shè)計(jì)了統(tǒng)一的容災(zāi)流程,整體流程如下:
圖 2
4.3 實(shí)現(xiàn)原理
4.3.1 端側(cè)容災(zāi) SDK
Web 端實(shí)現(xiàn)
Web 端的 CDN 資源主要是 JS、CSS 和圖片,所以我們的容災(zāi)目標(biāo)也聚焦于這些。在 Web 側(cè)的容災(zāi),我們主要實(shí)現(xiàn)了對(duì)靜態(tài)資源,異步資源和圖片資源的容災(zāi)。實(shí)現(xiàn)思路要實(shí)現(xiàn)資源的容災(zāi),最主要的問題是感知資源加載結(jié)果。通常我們是在資源標(biāo)簽上面添加錯(cuò)誤回調(diào)來捕獲,圖片容災(zāi)可以這樣實(shí)現(xiàn),但這并不適合 JS,因?yàn)樗袊?yán)格的執(zhí)行順序。為了解決這一問題,我們將傳統(tǒng)的標(biāo)簽加載資源的方式,換成XHR來實(shí)現(xiàn)。通過Webpack在工程構(gòu)建階段把同步資源進(jìn)行抽離,然后通過PhoenixLoader來加載資源。這樣就能通過網(wǎng)絡(luò)請(qǐng)求返回的狀態(tài)碼,來感知資源加載結(jié)果。在方案的實(shí)現(xiàn)上,我們將 SDK 設(shè)計(jì)成了 Webpack Plugin,主要基于以下四點(diǎn)考慮:
- 通用性:美團(tuán)前端技術(shù)棧相對(duì)較多,要保證容災(zāi) SDK 能夠覆蓋大部分的技術(shù)框架。
- 易用性:過高的接入成本會(huì)增加開發(fā)人員的工作量,不能做到對(duì)業(yè)務(wù)的有效覆蓋,方案價(jià)值也就無從談起。
- 穩(wěn)定性:方案要保持穩(wěn)定可靠,不受 CDN 可用性干擾。
- 侵入性:不能侵入到正常業(yè)務(wù),要做到即插即用,保證業(yè)務(wù)的穩(wěn)定性。
通過調(diào)研發(fā)現(xiàn),前端有 70%的工程構(gòu)建都離不開 Webpack,而 Webpack Plugin 獨(dú)立配置,即插即用的特性,是實(shí)現(xiàn)方案的最好選擇。整體方案設(shè)計(jì)如下:
圖 3
當(dāng)然,很多團(tuán)隊(duì)在做性能優(yōu)化時(shí),會(huì)采取代碼分割,按需引入的方式。這部分資源在同步資源生成的過程中無法感知,但這部分資源的加載結(jié)果,也關(guān)系到業(yè)務(wù)的可用性。在對(duì)異步資源的容災(zāi)方面,我們主要是通過對(duì) Webpack 的異步資源處理方式進(jìn)行重寫,使用Phoenix Loader接管資源加載,從而實(shí)現(xiàn)異步資源的容災(zāi)。整體分析過程如下圖所示:
圖 4
CSS 資源的處理與 JS 有所差別,但原理相似,只需要重寫 mini-css-extract-plugin 的異步加載實(shí)現(xiàn)即可。Web 端方案資源加載示意:
圖 5
容災(zāi)效果
圖6 容災(zāi)大盤
圖7 容災(zāi)案例
Native 端容災(zāi)
客戶端的 CDN 資源主要是圖片,音視頻以及各種動(dòng)態(tài)化方案的 bundle 資源。Native 端的容災(zāi)建設(shè)也主要圍繞上述資源展開。實(shí)現(xiàn)思路重新請(qǐng)求是 Native 端 CDN 容災(zāi)方案的基本原理,根據(jù)互備 CDN 域名,由 Native 容災(zāi)基建容災(zāi)域名重新進(jìn)行請(qǐng)求資源,整個(gè)過程發(fā)生在原始請(qǐng)求失敗后。Native 容災(zāi)基建不會(huì)在原始請(qǐng)求過程中進(jìn)行任何操作,避免對(duì)原始請(qǐng)求產(chǎn)生影響。原始請(qǐng)求失敗后,Native 容災(zāi)基建代理處理失敗返回,業(yè)務(wù)方仍處于等待結(jié)果狀態(tài),重請(qǐng)新求結(jié)束后向業(yè)務(wù)方返回最終結(jié)果。整個(gè)過程中從業(yè)務(wù)方角度來看仍只發(fā)出一次請(qǐng)求,收到一次結(jié)果,從而達(dá)到業(yè)務(wù)方不感知的目的。為將重新請(qǐng)求效率提升至最佳,必須盡可能的保證重新請(qǐng)求次數(shù)趨向于最小。調(diào)研業(yè)務(wù)的關(guān)注點(diǎn)和技術(shù)層面使用的網(wǎng)絡(luò)框架,結(jié)合 Phoenix 容災(zāi)方案的基本流程,在方案設(shè)計(jì)方面,我們主要考慮以下幾點(diǎn):
- 便捷性:接入的便捷性是 SDK 設(shè)計(jì)時(shí)首先考慮的內(nèi)容,即業(yè)務(wù)方可以用最簡(jiǎn)單的方式接入,實(shí)現(xiàn)資源容災(zāi),同時(shí)也可以簡(jiǎn)單無殘留拆除 SDK。
- 兼容性:Android 側(cè)的特殊性在于多樣的網(wǎng)絡(luò)框架,集團(tuán)內(nèi)包括 Retrofit 框架,okHttp 框架,okHttp3 框架及已經(jīng)很少使用的 URLConnection 框架。提供的 SDK 應(yīng)當(dāng)與各種網(wǎng)絡(luò)框架兼容,同時(shí)業(yè)務(wù)方在即使變更網(wǎng)絡(luò)框架也能夠以最小的成本實(shí)現(xiàn)容災(zāi)功能。而 iOS 側(cè)則考慮復(fù)用一個(gè) NSURLProtocol 去實(shí)現(xiàn)對(duì)請(qǐng)求的攔截,降低代碼的冗余度,同時(shí)實(shí)現(xiàn)對(duì)初始化項(xiàng)進(jìn)行統(tǒng)一適配。
- 擴(kuò)展性:需要在基礎(chǔ)功能之上提供可選的高級(jí)配置來滿足特殊需求,包括監(jiān)控方面也要提供特殊的監(jiān)控?cái)?shù)據(jù)上報(bào)能力。
基于以上設(shè)計(jì)要點(diǎn),我們將 Phoenix 劃分為以下結(jié)構(gòu)圖,圖中將整體的容災(zāi) SDK 拆分為兩部分 Phoenix-Adaptor 部分與 Phoenix-Base 部分。
圖 8
Phoenix-BasePhoenix-Base 是整個(gè) Phoenix 容災(zāi)的核心部分,其包括容災(zāi)數(shù)據(jù)緩存,域名更換組件,容災(zāi)請(qǐng)求執(zhí)行器(區(qū)別于原始請(qǐng)求執(zhí)行器),監(jiān)控器四個(gè)對(duì)外不可見的內(nèi)部功能模塊,并包含外部接入模塊,提供外部接入功能。
- 容災(zāi)數(shù)據(jù)緩存:定期獲取及更新容災(zāi)數(shù)據(jù),其產(chǎn)生的數(shù)據(jù)只會(huì)被域名更換組件使用。
- 域名更換組件:連接容災(zāi)數(shù)據(jù)緩存,容災(zāi)請(qǐng)求執(zhí)行器,監(jiān)控器的中心節(jié)點(diǎn),負(fù)責(zé)匹配原始失敗 Host,過濾錯(cuò)誤碼,并向容災(zāi)請(qǐng)求執(zhí)行器提供容災(zāi)域名,向監(jiān)控器提供整個(gè)容災(zāi)過程的詳細(xì)數(shù)據(jù)副本。
- 容災(zāi)執(zhí)行器:容災(zāi)請(qǐng)求的真正請(qǐng)求者,目前采用內(nèi)部 OkHttp3Client,業(yè)務(wù)方也可以自主切換至自身的執(zhí)行器。
- 監(jiān)控器:分發(fā)容災(zāi)過程的詳細(xì)數(shù)據(jù),內(nèi)置數(shù)據(jù)大盤的上報(bào),若有外部自定義的監(jiān)控器,也會(huì)向自定義監(jiān)控器分發(fā)數(shù)據(jù)。
Phoenix-AdaptorPhoenix-Adaptor 是 Phoenix 容災(zāi)的擴(kuò)展適配部分,用于兼容各種網(wǎng)絡(luò)框架。
- 綁定器:生成適合各個(gè)網(wǎng)絡(luò)框架的攔截器并綁定至原始請(qǐng)求執(zhí)行者。
- 解析器:將網(wǎng)絡(luò)框架的 Request 轉(zhuǎn)換為 Phoenix 內(nèi)部執(zhí)行器的 Request,并將 Phoenix 內(nèi)部執(zhí)行器的 Response 解析為外部網(wǎng)絡(luò)框架 Response,以此達(dá)到適配目的。
容災(zāi)效果① 業(yè)務(wù)成功率以外賣圖片業(yè)務(wù)為例,Android 業(yè)務(wù)成功率對(duì)比(同版本 7512,2021.01.17 未開啟 Phoenix 容災(zāi),2021.01.19 晚開啟 Phoenix 容災(zāi))。
圖 9iOS 業(yè)務(wù)成功率對(duì)比(同版本 7511,2021.01.17 未開啟 Phoenix 容災(zāi),2021.01.19 晚開啟 Phoenix 容災(zāi))。
圖 10② 風(fēng)險(xiǎn)應(yīng)對(duì)以外賣與美團(tuán)圖片做為對(duì)比 ,在 CDN 服務(wù)出現(xiàn)異常時(shí),接入 Phoenix 的外賣 App 和未接入的美團(tuán) App 在圖片成功率方面的對(duì)比。
圖 11
4.3.2 動(dòng)態(tài)計(jì)算服務(wù)
端側(cè)的域名重試,會(huì)在某一域名加載資源失敗后,根據(jù)容災(zāi)列表依次進(jìn)行重試,直至成功或者失敗。如下圖所示:
圖 12如果域名 A 大范圍異常,端側(cè)依然會(huì)首先進(jìn)行域名 A 的重試加載,這樣就導(dǎo)致不必要的重試成本。如何讓資源的首次加載更加穩(wěn)定有效,如何為不同業(yè)務(wù)和地區(qū)動(dòng)態(tài)提供最優(yōu)的 CDN 域名列表,這就是動(dòng)態(tài)計(jì)算服務(wù)的要解決的問題。計(jì)算原理動(dòng)態(tài)計(jì)算服務(wù)通過域名池和項(xiàng)目的 Appkey 進(jìn)行關(guān)聯(lián),按照不同省份、不同地級(jí)市、不同項(xiàng)目、不同資源等維度進(jìn)行策略管理。通過獲取 5 分鐘內(nèi)對(duì)應(yīng)項(xiàng)目上報(bào)的資源加載結(jié)果進(jìn)行定時(shí)輪詢計(jì)算,對(duì)域名池中的域名按照地區(qū)(城市&&省份)的可用性監(jiān)控。計(jì)算服務(wù)會(huì)根據(jù)域名可用性動(dòng)態(tài)調(diào)整域名順序并對(duì)結(jié)果進(jìn)行輸出。下圖是一次完整的計(jì)算過程:
圖 13
假設(shè)有 A、B、C 三個(gè)域名,成功率分別是 99%、98%、97.8%,流量占比分別是 90%、6%、4%?;谵D(zhuǎn)移基準(zhǔn),進(jìn)行流量轉(zhuǎn)移,比如,A 和 B 成功率差值是 1,B 需要把自己 1/2 的流量轉(zhuǎn)移給 A,同時(shí) A 和 C 的成功率差值大于 1,C 也需要把自己 1/2 的流量轉(zhuǎn)移給 A,同時(shí) B 和 C 的差值是 0.2,所以 C 還需要把自己 1/4 的流量轉(zhuǎn)移給 B。最終,經(jīng)過計(jì)算,A 的流量占比是 95%,B 是 3.5%,C 是 1.5%。最后,經(jīng)過排序和隨機(jī)計(jì)算后將最終結(jié)果輸出。因?yàn)?A 的占比最大,所以 A 優(yōu)先被選擇;通過隨機(jī),B 和 C 也會(huì)有一定的流量;基于轉(zhuǎn)移基準(zhǔn),可以實(shí)現(xiàn)流量的平穩(wěn)切換。異常喚起當(dāng)某個(gè) CDN 無法正常訪問的時(shí)候,該 CDN 訪問流量會(huì)由計(jì)算過程切換至等效的 CDN B。如果 SRE 發(fā)現(xiàn)切換過慢可以進(jìn)行手動(dòng)干預(yù)分配流量。當(dāng)少量的 A 域名成功率上升后,會(huì)重復(fù)計(jì)算過程將 A 的流量加大。直至恢復(fù)初始態(tài)。
圖 14
服務(wù)效果動(dòng)態(tài)計(jì)算服務(wù)使得資源的首次加載成功率由原來的99.7%提升至99.9%。下圖為接入動(dòng)態(tài)計(jì)算后資源加載成功率與未接入加載成功率對(duì)比。
圖 15
4.3.3 容災(zāi)監(jiān)控
在監(jiān)控層面,SRE 團(tuán)隊(duì)往往只關(guān)注域名、大區(qū)域、運(yùn)營(yíng)商等復(fù)合維度的監(jiān)控指標(biāo),監(jiān)控流量巨大,對(duì)于小流量業(yè)務(wù)或者小范圍區(qū)域的 CDN 波動(dòng),可能就無法被監(jiān)控分析識(shí)別,進(jìn)而也就無法感知 CDN 邊緣節(jié)點(diǎn)異常。容災(zāi)監(jiān)控建設(shè),主要是為了解決 SRE 團(tuán)隊(duì)的 CDN 監(jiān)控告警滯后和監(jiān)控粒度問題。監(jiān)控整體設(shè)計(jì)如下:
圖 16流程設(shè)計(jì)端側(cè)容災(zāi)數(shù)據(jù)的上報(bào),分別按照項(xiàng)目、App、資源、域名等維度建立監(jiān)控指標(biāo),將 CDN 可用性變成項(xiàng)目可用性的一部分。通過計(jì)算平臺(tái)對(duì)數(shù)據(jù)進(jìn)行分析聚合,形成 CDN 可用性大盤,按照域名、區(qū)域、項(xiàng)目、時(shí)間等維度進(jìn)行輸出,與天網(wǎng)監(jiān)控互通,建立分鐘級(jí)別的監(jiān)控告警機(jī)制,大大提升了 CDN 異常感知的靈敏性。同時(shí),SRE 側(cè)的天網(wǎng)監(jiān)控,也會(huì)對(duì)動(dòng)態(tài)計(jì)算服務(wù)結(jié)果產(chǎn)生干預(yù)。監(jiān)控整體流程如下:
圖 17監(jiān)控效果CDN 監(jiān)控不僅從項(xiàng)目維度更加細(xì)粒度的監(jiān)測(cè) CDN 可用性,還為 CDN 異常排查提供了區(qū)域、運(yùn)營(yíng)商、網(wǎng)絡(luò)狀況、返回碼等更豐富的信息。在監(jiān)控告警方面,實(shí)現(xiàn)了分鐘級(jí)異常告警,靈敏度也高于美團(tuán)內(nèi)部的監(jiān)控系統(tǒng)。
圖 18
4.3.4 CDN 服務(wù)
端側(cè)域名切換的有效性,離不開 CDN 服務(wù)的支持。在 CDN 服務(wù)方面,在原有 SRE 側(cè)容災(zāi)的基礎(chǔ)上,對(duì) CDN 服務(wù)整體做了升級(jí),實(shí)現(xiàn)域名隔離,解決了單域名對(duì)應(yīng)多 CDN 和多域名對(duì)應(yīng)單 CDN 重試無效的弊端。
圖 19
5. 總結(jié)與展望
經(jīng)過一年的建設(shè)與發(fā)展,Phoenix CDN 容災(zāi)方案日趨成熟,現(xiàn)已成為美團(tuán)在 CDN 容災(zāi)方面唯一的公共服務(wù),在多次 CDN 異常中發(fā)揮了巨大的作用。在端側(cè),當(dāng)前該方案日均容災(zāi)資源3000萬+,挽回用戶35萬+,覆蓋外賣,酒旅,餐飲,優(yōu)選,買菜等業(yè)務(wù)部門,服務(wù)200+個(gè)工程,外賣 App、美團(tuán) App、大眾點(diǎn)評(píng) App均已接入。在 SRE 側(cè),實(shí)現(xiàn)了項(xiàng)目維度的分鐘級(jí)精準(zhǔn)告警,同時(shí)豐富了異常信息,大大提高了 SRE 問題排查效率。自從方案大規(guī)模落地以來,CDN 異常時(shí)鮮有手動(dòng)切換操作,極大減輕了 SRE 同學(xué)的運(yùn)維壓力。由于前端技術(shù)的多樣性和復(fù)雜性,我們的 SDK 無法覆蓋所有的技術(shù)方案,所以在接下來的建設(shè)中,我們會(huì)積極推廣我們的容災(zāi)原理,公開動(dòng)態(tài)計(jì)算服務(wù),希望更多的框架和服務(wù)在我們的容災(zāi)思想上,貼合自身業(yè)務(wù)實(shí)現(xiàn)端側(cè)的 CDN 容災(zāi)。另外,針對(duì)方案本身,我們會(huì)不斷優(yōu)化資源加載性能,完善資源驗(yàn)簽,智能切換等能力,也歡迎對(duì) Phoenix CDN 容災(zāi)方案有興趣的同學(xué),跟我們一起探討交流。同時(shí)更歡迎加入我們,文末附招聘信息,期待你的郵件。
6. 作者簡(jiǎn)介
魏磊、陳彤、張群、粵俊等,均來自美團(tuán)外賣平臺(tái)-大前端團(tuán)隊(duì),丁磊、心澎,來自美團(tuán)餐飲 SaaS 團(tuán)隊(duì)。