轉(zhuǎn)載:京東618大促網(wǎng)關(guān)承載十億調(diào)用量背后的架構(gòu)實(shí)踐
618大促秕磷,我們的網(wǎng)關(guān)承載了幾十億的流量和調(diào)用,在這種情況下最欠,網(wǎng)關(guān)系統(tǒng)必須保證整個(gè)系統(tǒng)的穩(wěn)定性和高可用荚斯,保證高性能和可靠,以支撐業(yè)務(wù)霉颠。我們面臨的是一個(gè)非常復(fù)雜的問(wèn)題对碌,基于這種復(fù)雜問(wèn)題,怎樣做到很好地提高它的性能和穩(wěn)定性蒿偎、復(fù)雜技術(shù)之間怎么整合保證整體網(wǎng)關(guān)的高可用朽们,是本文的重點(diǎn)。
1 網(wǎng)關(guān)涵蓋技術(shù)
1.1 網(wǎng)關(guān)系統(tǒng)
網(wǎng)關(guān)系統(tǒng)主要有兩種:
第一種叫客戶端網(wǎng)關(guān)主要用來(lái)接收一些客戶端的請(qǐng)求诉位,也就是APP的服務(wù)端骑脱;
第二種叫開放網(wǎng)關(guān),主要是公司(比如京東)對(duì)于第三方合作伙伴提供接口不从。
這兩種不同網(wǎng)關(guān)所使用的技術(shù)非常類似惜姐。
流量比較大的網(wǎng)關(guān)面臨的難點(diǎn)包括:
第一犁跪,網(wǎng)關(guān)系統(tǒng)需要扛幾十億的流量調(diào)用椿息,接口的平穩(wěn)運(yùn)行歹袁、每一個(gè)接口在后端服務(wù)之后的性能耗損都非常重要。比如我們使用了一個(gè)Redis集群寝优,然后構(gòu)建了兩個(gè)機(jī)房条舔,每一個(gè)機(jī)房都搭建了一個(gè)Redis集群,這樣的話就能夠很好地保證高可用乏矾。在面對(duì)一個(gè)瞬間流量的時(shí)候孟抗,我們采用了一些緩存技術(shù),或者更前置的Nginx+lua+Redis技術(shù)钻心,讓這種大流量應(yīng)用能夠脫離開JVM的依賴凄硼。還有我們需要梳理各個(gè)接口,通過(guò)降級(jí)的策略把一些弱依賴的接口進(jìn)行降級(jí)捷沸,從而保證核心應(yīng)用的可用摊沉。
第二,網(wǎng)關(guān)系統(tǒng)其實(shí)就是一個(gè)把Http請(qǐng)求拓展到后端服務(wù)的過(guò)程痒给。我們的網(wǎng)關(guān)承接了一千以上的后端服務(wù)接口说墨,面對(duì)這種情況,怎樣做到服務(wù)與服務(wù)之間相互不影響苍柏?架構(gòu)層面怎樣能夠杜絕蝴蝶效應(yīng)尼斧、防止雪崩?就是說(shuō)當(dāng)一個(gè)接口出現(xiàn)問(wèn)題的時(shí)候试吁,不至于影響到其他接口的健康運(yùn)行棺棵。這個(gè)說(shuō)起來(lái)簡(jiǎn)單,但實(shí)際卻不然熄捍。
一千個(gè)以上的接口律秃,每個(gè)接口性能都不一致,而且每個(gè)接口所依賴的外部資源治唤、數(shù)據(jù)庫(kù)緩存等都不一樣棒动,幾乎每天都會(huì)出現(xiàn)各種各樣的問(wèn)題,我們?cè)鯓油ㄟ^(guò)一些隔離技術(shù)宾添、治理技術(shù)等船惨,保證當(dāng)這些接口出現(xiàn)問(wèn)題的時(shí)候,不會(huì)影響到全局缕陕?
第三粱锐,我們對(duì)外暴露了一千個(gè)服務(wù)接口,所有接口的后面意味著幾十個(gè)甚至上百個(gè)團(tuán)隊(duì)每天在不停地開發(fā)扛邑,每天都可能上線新的需求怜浅。面對(duì)這么復(fù)雜的情況,我們不可能每次后端服務(wù)器有任何修改,都需要有網(wǎng)關(guān)的修改或上線恶座,這樣網(wǎng)關(guān)會(huì)變得非常脆弱搀暑,穩(wěn)定性極低。
我們采用了一個(gè)動(dòng)態(tài)接入的技術(shù)跨琳,讓后端的網(wǎng)關(guān)能夠通過(guò)一種接入的協(xié)議進(jìn)行無(wú)縫接入自点,之后通過(guò)一些動(dòng)態(tài)代理的方式,直接讓后端的接口脉让,不管做任何修改或上線桂敛,都可以通過(guò)后端管理平臺(tái)從網(wǎng)關(guān)上對(duì)外進(jìn)行透?jìng)靼l(fā)布,很好地解決了我們網(wǎng)關(guān)所面臨的依賴于后端接口服務(wù)的上線問(wèn)題溅潜。
1.2 網(wǎng)關(guān)涵蓋技術(shù)
網(wǎng)關(guān)的四個(gè)技術(shù)方向:
第一术唬,統(tǒng)一接入。就是前端(包括APP或其他來(lái)源)的流量滚澜,能夠都在統(tǒng)一網(wǎng)絡(luò)層進(jìn)行接入碴开。這一層所面臨的問(wèn)題是:高性能透?jìng)鳌⒏卟l(fā)接入博秫、高可效性潦牛,以及當(dāng)前端流量來(lái)了之后,怎樣能夠進(jìn)行一個(gè)負(fù)載的往后端的轉(zhuǎn)發(fā)挡育。
第二巴碗,流量管控,主要指流量治理部分即寒。面對(duì)海量流量橡淆,我們?cè)鯓油ㄟ^(guò)一些防刷技術(shù),保障網(wǎng)關(guān)不被大流量沖垮母赵;以及怎樣通過(guò)一些像限流逸爵、降級(jí)、熔斷等技術(shù)凹嘲,對(duì)網(wǎng)關(guān)進(jìn)行全方位保護(hù)师倔。
第三,協(xié)議適配周蹭。就是前文提到的趋艘,網(wǎng)關(guān)會(huì)透?jìng)骱蠖松锨€(gè)服務(wù),而這些服務(wù)一定不是每一個(gè)都需要網(wǎng)關(guān)去開發(fā)配置的凶朗。我們通過(guò)一個(gè)協(xié)議適配的轉(zhuǎn)換瓷胧,讓后端的各種服務(wù)通過(guò)我們指定的協(xié)議、通過(guò)http的方式從網(wǎng)關(guān)開放出去棚愤,當(dāng)然網(wǎng)關(guān)不單單是http協(xié)議搓萧,還有一些TCP的。京東內(nèi)部的協(xié)議相對(duì)比較統(tǒng)一,有Http的restful的協(xié)議瘸洛,也有JSF的接口揍移,JSF是京東內(nèi)部自研的一個(gè)框架,一個(gè)RPC調(diào)用框架货矮,和double是類似的,然后基于注冊(cè)發(fā)現(xiàn)的一個(gè)rpc框架斯够。
第四囚玫,安全防護(hù)。這一部分對(duì)于網(wǎng)絡(luò)來(lái)說(shuō)非常重要读规,因?yàn)榫W(wǎng)關(guān)是整個(gè)公司對(duì)外的一個(gè)出口抓督,在這一層我們要做一些防刷,比如防清洗一些惡意流量束亏、做一些黑名單铃在,當(dāng)有一些惡意流量的話,通過(guò)限制IP等限制手段把它拒絕在整個(gè)網(wǎng)關(guān)之外碍遍,防止這些惡意流量把網(wǎng)關(guān)沖垮定铜。
2 自研網(wǎng)關(guān)架構(gòu)
2.1 自研網(wǎng)關(guān)架構(gòu)
我們的自研網(wǎng)關(guān)架構(gòu)主要分為三層。
第一層:接入層怕敬。主要負(fù)責(zé)一些長(zhǎng)短鏈接的接入揣炕、限流、黑白名單东跪、路由畸陡、負(fù)載均衡拦键、容災(zāi)切換等失晴。這一層所采用的技術(shù)是Nginx+lua的方式。
第二層:分發(fā)層(或者叫:網(wǎng)關(guān)的業(yè)務(wù)層)叹放。它更多的是NIO+Serviet3異步的技術(shù)斋日。在這一層中又分為幾個(gè)部分牲览。
● 最上層部分是數(shù)據(jù)校驗(yàn),在這一層會(huì)做一些簽名的校驗(yàn)恶守、時(shí)間的校驗(yàn)竭恬、和版本、方法等熬的。
● 下面一層叫泛化調(diào)用層痊硕,主要是把網(wǎng)關(guān)對(duì)外暴露的restful請(qǐng)求轉(zhuǎn)換成京東內(nèi)部的協(xié)議,進(jìn)行一個(gè)動(dòng)態(tài)適配調(diào)用的過(guò)程押框。這一塊我們更多使用的是一些緩存的技術(shù)岔绸,線程隔離、熔斷等技術(shù)也都是在這一層實(shí)現(xiàn)的。因?yàn)橛写罅繑?shù)據(jù)和協(xié)議的轉(zhuǎn)換盒揉,所以這一層用了多使用緩存的技術(shù)晋被,我們網(wǎng)關(guān)層所有的數(shù)據(jù)都不會(huì)直接穿透到DB,而是采用一個(gè)叫異構(gòu)數(shù)據(jù)的方式直接用緩存去做的刚盈。
泛化層中間有兩塊:一個(gè)叫主動(dòng)通知羡洛,另一個(gè)是沙箱測(cè)試。主動(dòng)通知很好理解藕漱,就是我們會(huì)通過(guò)這種TCP的下行通道及時(shí)通知到客戶端欲侮,發(fā)一些像京東賬戶優(yōu)惠券或提醒等;沙箱測(cè)試主要是說(shuō)我們?cè)谝恍┙涌诎l(fā)布上線之前肋联,進(jìn)行一個(gè)外部的測(cè)試威蕉。
如圖,最右側(cè)部分是服務(wù)降級(jí)橄仍、日志記錄韧涨、監(jiān)控告警,這三個(gè)都是我們整個(gè)網(wǎng)關(guān)的支撐系統(tǒng)侮繁。服務(wù)降級(jí)是說(shuō)當(dāng)有些服務(wù)出現(xiàn)問(wèn)題虑粥,第一時(shí)間把它降調(diào);日志是給我們排查問(wèn)題用的宪哩;監(jiān)控告警在下文會(huì)重點(diǎn)介紹舀奶,因?yàn)橐粋€(gè)網(wǎng)關(guān)的可用性很大方面是通過(guò)監(jiān)控系統(tǒng)來(lái)完善的,沒(méi)有監(jiān)控系統(tǒng)斋射、沒(méi)有告警育勺,就像沒(méi)有眼睛一樣,沒(méi)辦法知道任何事罗岖。
第三層:后端各種各樣的業(yè)務(wù)API(業(yè)務(wù)接口)涧至。這些接口通過(guò)網(wǎng)關(guān)對(duì)外進(jìn)行暴露。
整個(gè)網(wǎng)關(guān)大體上分為以上三層桑包,最上面的接入層南蓬、中間是網(wǎng)關(guān)的分發(fā)層,以及業(yè)務(wù)校驗(yàn)哑了、業(yè)務(wù)邏輯層赘方,然后通過(guò)網(wǎng)關(guān)透?jìng)髡?qǐng)求到后端服務(wù)。
除了這三層之外弱左,我們?cè)倏磧蛇叺南到y(tǒng)窄陡,都是我們整個(gè)網(wǎng)關(guān)比較核心和重要的支撐。
● 網(wǎng)關(guān)注冊(cè)中心拆火。后端各種各樣的接口可以通過(guò)網(wǎng)關(guān)注冊(cè)中心對(duì)外進(jìn)行發(fā)布跳夭,這個(gè)系統(tǒng)有一個(gè)類似管理界面涂圆,只要后端的API服務(wù)按照固有的協(xié)議進(jìn)行一個(gè)編寫,如果格式OK的話上傳到管理后臺(tái)币叹,一鍵就可以發(fā)布到線上润歉。當(dāng)然接口發(fā)布之前會(huì)有一個(gè)測(cè)試。
● OA鑒權(quán)中心颈抚。這一塊主要是做鑒權(quán)用的踩衩,像數(shù)據(jù)校驗(yàn)層的很多簽名的校驗(yàn)等安全校驗(yàn)都是在這一層統(tǒng)一做的。
2.2 技術(shù)棧
我們的網(wǎng)關(guān)系統(tǒng)所涉及到的一些技術(shù)棧:第一是接入層Nginx+lua技術(shù)贩汉;第二是NIO+Serviet3異步的技術(shù)驱富;第三是分離技術(shù);第四是降級(jí)限流雾鬼;第五是熔斷技術(shù)萌朱;第六是緩存宴树,哪些地方該加緩存策菜,哪些地方可以直接讀庫(kù);第七是異構(gòu)數(shù)據(jù)酒贬;第八是快速失斢趾;最后是監(jiān)控統(tǒng)計(jì)锭吨,這是整個(gè)高可用網(wǎng)關(guān)系統(tǒng)里非常重要的一部分蠢莺。
下文會(huì)針對(duì)這些技術(shù)所適用的場(chǎng)景進(jìn)行深入探討和分析,包括我們用這些技術(shù)解決什么問(wèn)題零如。
3 基本思路及過(guò)程改進(jìn)點(diǎn)
實(shí)踐 1 ?Nginx層統(tǒng)一接入
先看網(wǎng)關(guān)整個(gè)線上的部署架構(gòu)躏将,先通過(guò)一個(gè)軟負(fù)載LVS進(jìn)入到整個(gè)京東的網(wǎng)關(guān),第一層是核心Nginx考蕾,經(jīng)過(guò)核心Nginx之后就是后面的業(yè)務(wù)Nginx祸憋,然后通過(guò)業(yè)務(wù)Nginx把我們的請(qǐng)求透?jìng)鞯胶蠖说姆?wù)器。
核心Nginx主要是前端流量的分配肖卧,比如限流蚯窥、防刷都是在這層去做。下層是業(yè)務(wù)Nginx塞帐,主要的Nginx+lua的邏輯在這一層實(shí)現(xiàn)拦赠。這一層還有能減輕核心Nginx壓力、CPU壓力的作用葵姥,而且一些lua的應(yīng)用邏輯荷鼠,比如限流、防刷榔幸、鑒權(quán)颊咬、降級(jí)都是在這一層做的务甥。
為什么要加上Nginx+lua這一層?相較于Tomcat等喳篇,Nginx其實(shí)是一個(gè)能扛特別大并發(fā)流量的服務(wù)器敞临。基于這種狀況我們之前出現(xiàn)過(guò)問(wèn)題麸澜,當(dāng)這種并發(fā)流量特別大的時(shí)候挺尿,一旦后面出現(xiàn)單個(gè)機(jī)有問(wèn)題,哪怕你針對(duì)這個(gè)接口做了降級(jí)炊邦,但其實(shí)真正流量還是到了Tomcat層的JVM里编矾,當(dāng)流量很大的時(shí)候,很難通過(guò)JVM去消化掉這塊東西馁害,這樣導(dǎo)致的結(jié)果是:當(dāng)你的Tomcat出現(xiàn)問(wèn)題了窄俏,你很難通過(guò)重啟去解決這個(gè)問(wèn)題,因?yàn)榱髁繒?huì)一直存在碘菜,這臺(tái)Tomcat出問(wèn)題了凹蜈, 重啟完之后是把所有行動(dòng)都釋放了,但是它們就像病毒一樣忍啸,會(huì)來(lái)回傳染仰坦,你重啟了一批,這批馬上又被傳染到计雌。Nginx天然就是這種NIO異步的方式悄晃,能夠非常好地支持大并發(fā)的業(yè)務(wù)需求。所以我們把一些核心的凿滤,比如降級(jí)妈橄、流控等,都放在這一層翁脆,讓它替我們?cè)谧钋岸税蚜髁糠雷 ?/p>
實(shí)踐 2 引入NIO眷蚓、利用Servlet3異步化
第二個(gè)實(shí)踐是在Tomcat層引入了NIO,用了一個(gè)JDK7+TOMCAT7+Servlet3的配置鹃祖,讓同步請(qǐng)求變得異步化溪椎,然后利用NIO的多路復(fù)用處理技術(shù),讓我們能夠同時(shí)處理更高的并發(fā)數(shù)恬口。
利用Servlet3異步化之后可以提升吞吐量校读,但單個(gè)請(qǐng)求的響應(yīng)時(shí)間會(huì)略微變長(zhǎng),不過(guò)這種損耗是可以忍受的祖能,因?yàn)檫@會(huì)帶來(lái)整個(gè)應(yīng)用吞吐量的增加和靈活性的增強(qiáng)歉秫。還是非常值得我們使用的。
具體采用策略:業(yè)務(wù)方法開啟異步化上下文AsynContext;釋放tomcat當(dāng)前處理線程养铸;tomcat該線程被釋放雁芙,然后用于下次請(qǐng)求的處理轧膘,提高其吞吐量;在AsynContext環(huán)境中完成業(yè)務(wù)方法的處理兔甘,調(diào)用其complete方法谎碍,將響應(yīng)寫回響應(yīng)流。這樣可以提高tomcat業(yè)務(wù)邏輯的可能性洞焙,讓我們?cè)谶@一層非常少的線程數(shù)就能處理更多的請(qǐng)求蟆淀,而不至于當(dāng)流量非常大的時(shí)候會(huì)被壓垮。
實(shí)踐 3 分離之術(shù)
本節(jié)將在所有分離技術(shù)中挑兩個(gè)比較重點(diǎn)的進(jìn)行分享澡匪。
請(qǐng)求解析和業(yè)務(wù)處理分離
第一個(gè)是通過(guò)NIO的方式熔任,把請(qǐng)求解析的線程和后面處理的業(yè)務(wù)線程進(jìn)行分離。
請(qǐng)求由tomcat單線程處理唁情,在NIO模式下可以用非常少量線程處理大量鏈接情況疑苔。業(yè)務(wù)邏輯處理和生成響應(yīng)都是由另外的tomcat線程池處理,從而跟請(qǐng)求線程隔離甸鸟。這里的業(yè)務(wù)線程池還可以進(jìn)一步隔離惦费,不同業(yè)務(wù)設(shè)置不同的線程池。
業(yè)務(wù)線程池分離
第二個(gè)是業(yè)務(wù)線程池分離哀墓,就是通過(guò)一個(gè)線程的隔離技術(shù)趁餐,把不同的接口或不同類型的接口進(jìn)行隔離喷兼。比如訂單相關(guān)的接口篮绰,拿20個(gè)單獨(dú)線程去處理;商品相關(guān)的接口季惯,拿10個(gè)單獨(dú)的線程去處理吠各,這樣的話就可以讓不同的接口之間互不影響,如果訂單這塊有一個(gè)出了問(wèn)題勉抓,最多消耗它自己贾漏,不會(huì)影響到其他接口的線程的調(diào)用。
具體的線程隔離可以根據(jù)業(yè)務(wù)來(lái)指定一組線程的數(shù)量藕筋,這幾個(gè)線程是為固定接口準(zhǔn)備的纵散,當(dāng)這個(gè)接口出現(xiàn)問(wèn)題,它就把自己的線程數(shù)用掉了隐圾,不會(huì)去占用其他接口的線程伍掀,這樣起到了線程隔離的作用,讓單個(gè)API出問(wèn)題的時(shí)候不會(huì)影響到其他暇藏。
實(shí)踐 4 降級(jí)
降級(jí)主要是說(shuō)當(dāng)有某個(gè)接口出現(xiàn)問(wèn)題蜜笤,我們能夠把這個(gè)接口直接降調(diào),讓它調(diào)用直接返回盐碱,不會(huì)用到其他應(yīng)用把兔。還有就是如果某一塊弱一點(diǎn)的業(yè)務(wù)邏輯出現(xiàn)問(wèn)題沪伙,我們直接把這塊邏輯降調(diào),不至于影響到其他的黃金邏輯县好。
降級(jí)怎么做围橡?
首先,降級(jí)開關(guān)要集中化管理缕贡,比如通過(guò)zookeeper推送到各個(gè)應(yīng)用服務(wù)某饰。這樣才能在出現(xiàn)問(wèn)題的第一時(shí)間找到對(duì)應(yīng)開關(guān)做降級(jí)處理。
一個(gè)基于開發(fā)降級(jí)的統(tǒng)一配置本身這個(gè)系統(tǒng)要是高可用的善绎、支持多維度的緩存黔漂,比如我們?nèi)绻脄ookeeper實(shí)現(xiàn),首先zookeeper會(huì)有數(shù)據(jù)庫(kù)存儲(chǔ)禀酱,再上面會(huì)有一個(gè)本地緩存炬守。再就是我們會(huì)有一個(gè)快照,如果zookeeper讀不到緩存剂跟,會(huì)通過(guò)快照去加載進(jìn)來(lái)一些托底的數(shù)據(jù)减途,以保證開發(fā)一旦觸發(fā)之后能夠在第一時(shí)間響應(yīng)。而我們的開關(guān)也不至于會(huì)成為其他系統(tǒng)的問(wèn)題曹洽,它是非常弱化鳍置、非常薄的一層。
精細(xì)化流量控制
說(shuō)完開關(guān)送淆、流量控制和降級(jí)之后税产,我們來(lái)看通過(guò)多維度的流量控制和降級(jí)的策略,比如按照單個(gè)API或API+地域偷崩、運(yùn)營(yíng)商等維度進(jìn)行控制辟拷。一旦出問(wèn)題了,我們會(huì)把多種組合方式進(jìn)行降級(jí)阐斜,還可以根據(jù)秒/分鐘級(jí)等不同維度進(jìn)行流量控制衫冻,從而達(dá)到精細(xì)化流量管理。
優(yōu)雅降級(jí)
說(shuō)到降級(jí)谒出,前面說(shuō)的更多的是技術(shù)層面的隅俘,在業(yè)務(wù)層面的話,我們也要講究?jī)?yōu)雅降級(jí)笤喳。我們不能說(shuō)這個(gè)邏輯一旦建立之后就直接返回前端502为居,這肯定是不友好的。我們肯定會(huì)跟前端進(jìn)行溝通莉测,比如降級(jí)之后反饋給前端一個(gè)對(duì)應(yīng)的錯(cuò)誤碼颜骤,或者給用戶反饋一個(gè)提示等操作指令,這樣能夠讓用戶體驗(yàn)更好一些捣卤。
實(shí)踐 5 限流
惡意請(qǐng)求忍抽、惡意攻擊八孝,惡意的請(qǐng)求流量可以只訪問(wèn)cache,惡意的IP可以使用nginx層的 deny進(jìn)行屛蔽鸠项;
防止流程超出系統(tǒng)的承載能力干跛,雖然會(huì)預(yù)估但總有意外,如果沒(méi)有限流祟绊,當(dāng)超過(guò)系統(tǒng)承載峰值的時(shí)候楼入,整個(gè)系統(tǒng)就會(huì)打垮。
實(shí)踐 6 熔斷
當(dāng)我們的后端機(jī)構(gòu)出現(xiàn)問(wèn)題了牧抽,達(dá)到某個(gè)閥值了嘉熊,系統(tǒng)就能夠自動(dòng)進(jìn)行關(guān)閉降級(jí),這是熔斷的大體思路扬舒。我們會(huì)有更靈活的配置:比如當(dāng)某個(gè)接口接連三次訪問(wèn)超時(shí)或返回錯(cuò)誤的話就自動(dòng)熔斷阐肤;也可以是配置一些超時(shí)間,比如連續(xù)三次這種方法調(diào)用的性能都超過(guò)了50毫秒讲坎,就會(huì)自動(dòng)對(duì)這個(gè)方法進(jìn)行熔斷孕惜,熔斷之后就相當(dāng)于降級(jí)了,再次調(diào)用的話會(huì)返回失敗晨炕,就是直接拒絕返回了衫画。
熔斷之后還可以有一個(gè)設(shè)置:比如5秒或一分鐘之后出來(lái)一個(gè)半打開狀態(tài),再次醒來(lái)之后瓮栗,它會(huì)去試探一下當(dāng)天這個(gè)服務(wù)是否已經(jīng)OK了削罩,如果沒(méi)有問(wèn)題了,它就會(huì)去把你之前熔斷的API業(yè)務(wù)再次打開遵馆,能夠正常對(duì)外提供服務(wù)【ń迹現(xiàn)在有一些開源的實(shí)踐丰榴,通過(guò)這些實(shí)踐可以很好的做熔斷货邓,當(dāng)然根據(jù)這里邊的思路,自己也可以實(shí)現(xiàn)四濒,這不是特別復(fù)雜的事情换况。
實(shí)踐 7 快速失敗-鏈路中的超時(shí)
快速失敗是非常重要的一個(gè)實(shí)踐,不光是做網(wǎng)關(guān)系統(tǒng)盗蟆,做其他系統(tǒng)也要記住戈二,特別是調(diào)用量大的系統(tǒng),比如注意到整個(gè)鏈條中的超時(shí)設(shè)置喳资。這是我們每年在做雙11和618備戰(zhàn)的時(shí)候觉吭,都需要重點(diǎn)去review的一塊東西,包括我們平時(shí)在做開發(fā)的時(shí)候仆邓、每一次新模塊上線之前鲜滩,我們都要重點(diǎn)去監(jiān)控這一塊伴鳖。我們會(huì)梳理所有系統(tǒng)對(duì)外的依賴,比如網(wǎng)關(guān)依賴于我們自己的一些業(yè)務(wù)的緩存徙硅、數(shù)據(jù)庫(kù)榜聂,更多的是依賴于后端數(shù)千個(gè)不同的服務(wù)。
這種涉及到網(wǎng)絡(luò)的嗓蘑,我們必須要設(shè)置超時(shí)間须肆,因?yàn)橄窬W(wǎng)關(guān)這種調(diào)用量比較大的系統(tǒng),如果不設(shè)超時(shí)間桩皿,有可能它默認(rèn)時(shí)間就是幾分鐘豌汇,這么長(zhǎng)時(shí)間,一旦有一個(gè)機(jī)構(gòu)出問(wèn)題了泄隔,有可能瞬間整個(gè)網(wǎng)關(guān)系統(tǒng)會(huì)全部雪崩掉瘤礁,任何一個(gè)接口都不能對(duì)外使用,因?yàn)閿?shù)據(jù)量很大梅尤,有可能你都來(lái)不及降級(jí)就已經(jīng)被沖垮了柜思。
實(shí)踐 8 監(jiān)控統(tǒng)計(jì)-應(yīng)用層
監(jiān)控統(tǒng)計(jì)是網(wǎng)關(guān)系統(tǒng)里非常核心的一部分,只有有了監(jiān)控巷燥,有了報(bào)警赡盘,才能讓我們實(shí)時(shí)了解所有的運(yùn)營(yíng)情況、每一個(gè)API調(diào)用的情況缰揪。
監(jiān)控目標(biāo)
第一:保證7*24小時(shí)守護(hù)系統(tǒng)陨享;
第二:能夠?qū)崟r(shí)監(jiān)控系統(tǒng)的運(yùn)營(yíng)狀況,比如哪個(gè)API是不是調(diào)用時(shí)間過(guò)長(zhǎng)了钝腺?哪個(gè)API已經(jīng)熔斷了抛姑?等等;
第三:統(tǒng)計(jì)數(shù)據(jù)艳狐,分析指標(biāo)定硝。比如一天過(guò)去了,每一個(gè)API調(diào)用情況有沒(méi)有超時(shí)毫目?有沒(méi)有訪問(wèn)的性能降低等蔬啡;
第四:實(shí)時(shí)報(bào)警。因?yàn)楸O(jiān)控是一部分镀虐,發(fā)現(xiàn)問(wèn)題之后能夠第一時(shí)間通知到我們箱蟆,讓我們能夠馬上處理也是讓系統(tǒng)更加健康的一個(gè)方面。
監(jiān)控范圍
監(jiān)控的維度
第一層:硬件監(jiān)控刮便。比如系統(tǒng)的CPU內(nèi)存空猜、網(wǎng)卡等。
第二層:自定義監(jiān)控。比如直接報(bào)警辈毯。
第三層:性能監(jiān)控久信。比如每個(gè)接口的TP指標(biāo),TP999 TP99 TP90 TP50四種性能指標(biāo)作為SLA的參考標(biāo)準(zhǔn)漓摩,還有可用率等裙士,這個(gè)對(duì)于網(wǎng)關(guān)來(lái)說(shuō)至關(guān)重要。
第四層:心跳監(jiān)控管毙。網(wǎng)關(guān)系統(tǒng)線上有很多機(jī)器腿椎,每個(gè)機(jī)器現(xiàn)在的情況怎樣?有沒(méi)有存貨等夭咬。
第五層:業(yè)務(wù)層監(jiān)控啃炸。比如我們會(huì)有一些JVM監(jiān)控,監(jiān)控Nginx連接數(shù)等卓舵。
在京東內(nèi)部有一個(gè)很完善的監(jiān)控體系南用,叫UMP系統(tǒng),能夠幫助我們做各個(gè)層級(jí)的監(jiān)控掏湾。它主要是提供給我們一些類似于配置的文件裹虫,我們配置好之后就可以進(jìn)行系統(tǒng)的監(jiān)控,我們?cè)谧龅臅r(shí)候會(huì)通過(guò)一些AOP代理的方式融击,對(duì)所有的方法進(jìn)行監(jiān)控筑公。因?yàn)槲覀兪蔷W(wǎng)關(guān),需要大量的后端透?jìng)髯鹄耍W(wǎng)關(guān)因?yàn)槭莿?dòng)態(tài)地生成這些接口匣屡,根本不知道有哪些接口,所以在動(dòng)態(tài)生成接口的時(shí)候自動(dòng)地AOP給它注入一個(gè)個(gè)監(jiān)控拇涤,這樣的話就是每一個(gè)接口都能夠有一個(gè)監(jiān)控捣作。
說(shuō)到監(jiān)控不得不提的是,我們做網(wǎng)關(guān)系統(tǒng)就是做透?jìng)鞯亩焓浚竺嬗懈鞣N各樣不同的接口券躁、業(yè)務(wù)邏輯,每個(gè)業(yè)務(wù)邏輯和接口的性能都需要去監(jiān)控如绸,然后告知對(duì)方讓對(duì)方去整改的嘱朽,所以我們除了把這些監(jiān)控加完之后,有了問(wèn)題要能夠通知到對(duì)應(yīng)的負(fù)責(zé)人怔接,包括我們自己。所以我們每一天每一周都會(huì)有郵件以報(bào)表形式發(fā)出稀轨,讓所有系統(tǒng)負(fù)責(zé)人都知道對(duì)應(yīng)的機(jī)構(gòu)的情況扼脐,比如性能是否有問(wèn)題、是否需要整改等。
由于時(shí)間關(guān)系瓦侮,本次分享到此結(jié)束艰赞,我將會(huì)在11月9-12日國(guó)家會(huì)議中心舉辦的TOP100全球軟件案例研究峰會(huì)進(jìn)行更加深入的分享,歡迎到場(chǎng)交流肚吏。
進(jìn)入“閱讀原文”方妖,點(diǎn)擊“獲取免費(fèi)體驗(yàn)票”有機(jī)會(huì)獲得開幕式單天免費(fèi)體驗(yàn)票,50個(gè)名額罚攀,手慢無(wú)~