如何構(gòu)建一個(gè)流量無損的在線應(yīng)用架構(gòu)
這一篇主要從數(shù)據(jù)交換的維度闡明數(shù)據(jù)交換的過程如何影響到線上流量;最后會(huì)引入兩個(gè)常用的防范措施:全鏈路壓測(cè)和安全生產(chǎn)演練。我們先來說說數(shù)據(jù)交換部分:
數(shù)據(jù)
當(dāng)流量在應(yīng)用集群中流轉(zhuǎn)完畢之后,他行至的終點(diǎn)一般是將數(shù)據(jù)與各種類型的數(shù)據(jù)服務(wù)進(jìn)行交換,如:從緩存讀取數(shù)據(jù)返回、將訂單記錄存儲(chǔ)在數(shù)據(jù)庫(kù)中、將交易數(shù)據(jù)與外圍的支付服務(wù)進(jìn)行數(shù)據(jù)交換等。但是只要是和外面的服務(wù)進(jìn)行數(shù)據(jù)訪問,就會(huì)出現(xiàn)外圍服務(wù)不可用的情況,常見的一些情況比如:因?yàn)楸灰蕾囘^重或數(shù)據(jù)過載而導(dǎo)致雪崩,因?yàn)閿?shù)據(jù)中心整體不可用導(dǎo)致大面積癱瘓。比如最近一個(gè)比較有名的事件就是 Meta 公司的大規(guī)模宕機(jī)事件,其原因正是下發(fā)了一條錯(cuò)誤的配置切斷了數(shù)據(jù)中心之間的主干路由。
1. 常用解決方案:分庫(kù)分表
針對(duì)國(guó)內(nèi)互聯(lián)網(wǎng)公司海量數(shù)據(jù)的場(chǎng)景,當(dāng)我們的業(yè)務(wù)成長(zhǎng)到一定的階段就會(huì)帶來緩存或者 DB 的容量問題,以 MySQL 舉例子,當(dāng)單表的容量在千萬級(jí)別的時(shí)候,如果這張表還需要和其他表進(jìn)行關(guān)聯(lián)查詢,就會(huì)出現(xiàn)數(shù)據(jù)庫(kù)在 IO、CPU 各方面的壓力。此時(shí)就需要開始考慮分庫(kù)分表的方案。但是分完了之后并不是一蹴而就,他會(huì)引入諸如分布式事務(wù)、聯(lián)合查詢、跨庫(kù) Join 等新的問題,每個(gè)問題如果人肉去搞定會(huì)更加的棘手,不過好在市面上針對(duì)這些領(lǐng)域也出現(xiàn)了很多優(yōu)秀的框架,比如社區(qū)的 Sharding JDBC,阿里云剛剛開源的 PolarDB-X 等。
2. 常用解決方案:數(shù)據(jù)中心容災(zāi)
為防止數(shù)據(jù)中心出現(xiàn)整體不可用的情況,一個(gè)常規(guī)的思路是需要針對(duì)性建設(shè)好容災(zāi)多活的高可用能力,數(shù)據(jù)中心級(jí)別的容災(zāi)常見的是同城和異地,但一個(gè)數(shù)據(jù)中心部署的服務(wù)很可能是分布式服務(wù),針對(duì)每一個(gè)分布式服務(wù)的容災(zāi)策略都略有不同,本篇以常見的 MySQL 來舉例子說一些常見的思路。
容災(zāi)的核心是需要解決 CAP 中的兩個(gè)問題,即:C(數(shù)據(jù)一致性)、A(服務(wù)可用性),但是根據(jù) CAP 理論我們只能保 CP 和 AP 中的一個(gè),所以這里到底選擇什么樣子的策略,其實(shí)是需要根據(jù)業(yè)務(wù)形態(tài)來制定的。對(duì)于同城 IDC 級(jí)別的容災(zāi)而言,由于他的 RT 一般都很小,數(shù)據(jù)一致性上能最大的得以滿足。只是在 Paxos(MySQL 中的一致性算法)的 Master 節(jié)點(diǎn)所在的機(jī)房如果掛掉的情況下,會(huì)面臨再次選主,如果集群較大可能會(huì)因?yàn)檫x主造成的幾十秒級(jí)別 DB 不可用的情況。而對(duì)于異地場(chǎng)景而言,由于數(shù)據(jù)鏈路太長(zhǎng)的問題,他的數(shù)據(jù)一致性基本上不可能滿足,所以業(yè)務(wù)必須配合改造,做到業(yè)務(wù)級(jí)別的橫向切分,如:華南數(shù)據(jù)中心服務(wù)華南客戶群體,華北數(shù)據(jù)中心服務(wù)華北客戶群體。而分片的數(shù)據(jù)再通過數(shù)據(jù)同步的方式做到最終一致性。
防范
到這里基本上說完了在線上應(yīng)用的四個(gè)核心環(huán)節(jié)中,尤其提及了容易由于架構(gòu)設(shè)計(jì)、基礎(chǔ)設(shè)施脆弱等原因而造成的流量有損的點(diǎn),也列舉了對(duì)應(yīng)場(chǎng)景下的解決方案。不過站在安全生產(chǎn)的角度上,一切安全生產(chǎn)的目的都是防范于未然。在互聯(lián)網(wǎng)的系統(tǒng)中相比較于傳統(tǒng)的軟件產(chǎn)品,我們推薦兩個(gè)在生產(chǎn)級(jí)別進(jìn)行防范的方法:全鏈路壓測(cè)和安全生產(chǎn)線上演練(也叫故障演練)。
1. 全鏈路壓測(cè)
在軟件產(chǎn)品的生產(chǎn)體系中,任何一個(gè)即將上線的系統(tǒng),我們都會(huì)進(jìn)行各種目標(biāo)的測(cè)試,其中就包括壓力測(cè)試,即:使系統(tǒng)處于一個(gè)頗為嚴(yán)苛的環(huán)境中,來觀看系統(tǒng)的表現(xiàn)。而一般的壓力測(cè)試,只會(huì)針對(duì)性的構(gòu)造相應(yīng)的接口對(duì)線下部署的環(huán)境服務(wù)進(jìn)行相應(yīng)的壓力測(cè)試,而且測(cè)試報(bào)告不出意外都是很完美的;但這樣的壓力測(cè)試會(huì)有幾個(gè)問題:
- 由于線上線下的依賴環(huán)境差異很大,而評(píng)估不到真實(shí)的線上系統(tǒng)容量。
- 壓測(cè)過程的數(shù)據(jù)不豐富,覆蓋面窄而造成場(chǎng)景遺漏。
- 由于壓測(cè)的流量或者工具不夠健全,只能評(píng)估到單臺(tái)機(jī)器或服務(wù),而非整個(gè)生產(chǎn)集群。
如果要做到全面、系統(tǒng)、且真實(shí)的流量評(píng)估,我們推薦直接使用生產(chǎn)環(huán)境針對(duì)性的進(jìn)行性能壓測(cè),但要想做到這樣的全鏈路的壓力測(cè)試,有很多的技術(shù)瓶頸需要突破,其中包括:
- 有一套能力強(qiáng)大能構(gòu)建出豐富場(chǎng)景的工具體系或產(chǎn)品。
- 整體服務(wù)鏈路上,支持從流量入口開始的壓測(cè)標(biāo)示傳遞。
- 系統(tǒng)中使用的中間件能識(shí)別正常流量與壓測(cè)流量。
- 業(yè)務(wù)需要針對(duì)壓測(cè)流量作出業(yè)務(wù)改造(如影子表),以免壓測(cè)數(shù)據(jù)影響到線上的真實(shí)數(shù)據(jù)。
但是在執(zhí)行過程中,由于全鏈路的影響面太大,在正式開始大流量的壓測(cè)之前,需要逐步實(shí)施前期的準(zhǔn)備工作,其中包括:壓測(cè)方案制定、預(yù)跑驗(yàn)證、壓測(cè)預(yù)熱,最后才是正式壓測(cè)。壓測(cè)完畢還需要針對(duì)壓測(cè)結(jié)果進(jìn)行分析,以確保整個(gè)系統(tǒng)符合預(yù)先設(shè)定的目標(biāo)。
2. 安全生產(chǎn)演練
與全鏈路壓測(cè)的思路類似,為了盡可能的貼近生產(chǎn)環(huán)境,安全生產(chǎn)演練我們也是推薦在線上完成。演練的目的是檢驗(yàn)系統(tǒng)在各種不可預(yù)知的服務(wù)不可用、基礎(chǔ)實(shí)施故障或者依賴失效的情況下,來檢驗(yàn)系統(tǒng)的行為表現(xiàn)是否依然健壯。通常演練的范圍從單應(yīng)用到服務(wù)集群,甚至到整機(jī)房基礎(chǔ)設(shè)施依次上升。演練場(chǎng)景可以從進(jìn)程內(nèi)(如:請(qǐng)求超時(shí))、進(jìn)程級(jí)別(如:FullGC)、容器(如:CPU 高),再到 Kubernetes 集群(如:Pod驅(qū)逐、ETCD 故障等)各個(gè)場(chǎng)景疊加,根據(jù)業(yè)務(wù)系統(tǒng)的反脆弱能力,針對(duì)性的作出選擇。
結(jié)語(yǔ)
文中很多場(chǎng)景和技術(shù)點(diǎn)都是來源于真實(shí)的線上系統(tǒng)的真實(shí)故障。我們將這些年在每一個(gè)環(huán)節(jié)中的相應(yīng)解決方案,以產(chǎn)品化的方式沉淀到企業(yè)級(jí)分布式應(yīng)用服務(wù)(EDAS)中。EDAS 致力于解決在線應(yīng)用的全流程流量無損,經(jīng)過 6 年的精細(xì)打磨,已經(jīng)在流量接入與流量服務(wù)兩個(gè)關(guān)鍵位置為我們的客戶提供了流量無損的關(guān)鍵能力,我們接下來的主要目標(biāo)也是將這一能力貫穿應(yīng)用的全流程,讓您的應(yīng)用默認(rèn)能具備全流程的流量無損,極力保障商業(yè)能力的可持續(xù)性。