分布式鏈路異常日志采集方法研究
引言
隨著互聯(lián)網(wǎng)業(yè)務(wù)快速擴(kuò)展,軟件架構(gòu)設(shè)計(jì)也變得愈發(fā)復(fù)雜,為滿足大量客戶高并發(fā)的請(qǐng)求,系統(tǒng)逐步走向分布式,如單體架構(gòu)的服務(wù)拆分為微服務(wù),這些微服務(wù)構(gòu)成了復(fù)雜的分布式網(wǎng)絡(luò)。同時(shí),復(fù)雜的分布式調(diào)用網(wǎng)絡(luò)可能會(huì)有成千上萬(wàn)的服務(wù),如果一個(gè)服務(wù)出現(xiàn)問(wèn)題,可能會(huì)導(dǎo)致數(shù)十個(gè)服務(wù)出現(xiàn)異常,對(duì)異常問(wèn)題的排查將十分困難。
分布式鏈路跟蹤是將分布式請(qǐng)求還原成請(qǐng)求的調(diào)用鏈路,如一次點(diǎn)擊請(qǐng)求的處理過(guò)程,經(jīng)過(guò)多個(gè)服務(wù)及實(shí)例。當(dāng)出現(xiàn)異常節(jié)點(diǎn)時(shí),需采集異常節(jié)點(diǎn)的全鏈路信息,文獻(xiàn)探討了基于采樣方式采集異常鏈路,該策略能提升異常鏈路采集速率,但實(shí)際生產(chǎn)中99.99%的非異常日志對(duì)問(wèn)題排查作用不大,而0.01%的異常日志則起到關(guān)鍵作用。在保證異常日志鏈路查全率的前提下,提高異常日志采集速率能在業(yè)務(wù)高峰期起到重要作用。
本文提出了一種分布式鏈路異常日志采集方法,能在保證異常日志鏈路查全率的前提下,提高異常日志采集速率,以提升服務(wù)異常時(shí)的運(yùn)維排查效率。
1分布式技術(shù)
1.1分布式系統(tǒng)
分布式系統(tǒng)是指由多臺(tái)在網(wǎng)絡(luò)上分散的計(jì)算機(jī)通過(guò)網(wǎng)絡(luò)連接而成的系統(tǒng),系統(tǒng)的計(jì)算處理邏輯和控制功能分布在這個(gè)系統(tǒng)網(wǎng)絡(luò)的計(jì)算機(jī)上。而計(jì)算機(jī)的分布式部署就是將微服務(wù)應(yīng)用有規(guī)則地分散在多臺(tái)獨(dú)立運(yùn)行的計(jì)算機(jī)設(shè)備上,同一功能的微服務(wù)應(yīng)用可能同時(shí)部署到多臺(tái)計(jì)算機(jī)上,利用多臺(tái)計(jì)算機(jī)服務(wù)器進(jìn)行應(yīng)用的負(fù)載均衡。
1.2鏈路跟蹤
鏈路跟蹤在請(qǐng)求調(diào)用鏈路還原、調(diào)用網(wǎng)絡(luò)重構(gòu)方面對(duì)分布式服務(wù)起到關(guān)鍵作用,可以協(xié)助運(yùn)維人員快速定位分布式服務(wù)框架下的請(qǐng)求調(diào)用鏈路,提高微服務(wù)的運(yùn)維定位效率。
一個(gè)請(qǐng)求接口內(nèi)可能調(diào)用了多個(gè)應(yīng)用服務(wù),排查接口內(nèi)的異常節(jié)點(diǎn),需要清楚請(qǐng)求服務(wù)調(diào)用多個(gè)服務(wù)的順序,就是調(diào)用鏈。為了實(shí)現(xiàn)調(diào)用鏈,對(duì)請(qǐng)求調(diào)用的每個(gè)服務(wù)按先后排序標(biāo)記唯一標(biāo)志,該標(biāo)志定義為spanId:為了標(biāo)志每次請(qǐng)求的調(diào)用情況,需要對(duì)每一次請(qǐng)求也標(biāo)記唯一標(biāo)志,該標(biāo)志定義為traceId,如圖1所示。
1.3翻滾時(shí)間窗口
翻滾時(shí)間窗口指的是讀取數(shù)據(jù)的窗口所含時(shí)間長(zhǎng)度固定,若時(shí)間窗口設(shè)定為ns,則該時(shí)間窗口只讀取當(dāng)前ns內(nèi)的數(shù)據(jù),而不會(huì)讀取前ns或后ns的數(shù)據(jù),且時(shí)間連續(xù),窗口不會(huì)出現(xiàn)重疊。
2框架構(gòu)建
2.1基于翻滾移動(dòng)窗口實(shí)時(shí)提取分布式流數(shù)據(jù)方案
隨著業(yè)務(wù)的辦理,業(yè)務(wù)執(zhí)行日志將不斷產(chǎn)生,并實(shí)時(shí)寫入日志服務(wù)器。由于日志數(shù)據(jù)是實(shí)時(shí)產(chǎn)生并寫入日志服務(wù)器的,讀取日志數(shù)據(jù)就是一個(gè)面向流處理的場(chǎng)景,并非批處理的場(chǎng)景。每個(gè)日志服務(wù)器上的數(shù)據(jù)都是從上到下逐條寫入,且時(shí)間上是順序的。
因此,基于翻滾時(shí)間移動(dòng)窗口讀取日志流數(shù)據(jù),該方案是每次在日志服務(wù)器從上到下按照固定時(shí)間長(zhǎng)度非重復(fù)性地讀取該時(shí)間段內(nèi)日志數(shù)據(jù)。時(shí)間窗口是基于歷史統(tǒng)計(jì)請(qǐng)求的最長(zhǎng)時(shí)間x1.1獲得,應(yīng)用歷史統(tǒng)計(jì)最長(zhǎng)時(shí)長(zhǎng)記為Regmax,時(shí)間窗口寬度記為W,即W=Regmax×1.1。
2.2日志數(shù)據(jù)暫存
每個(gè)時(shí)間窗口寬度提取出的日志數(shù)據(jù)將作為一個(gè)集合,并對(duì)每個(gè)集合按從小到大的順序分配編號(hào)setId(eg:l,2,3,…)。同時(shí),對(duì)當(dāng)前集合的每條數(shù)據(jù)進(jìn)行遍歷,每條日志數(shù)據(jù)所含的標(biāo)志字段有:traceId(請(qǐng)求標(biāo)志)、status(請(qǐng)求狀態(tài))。由于請(qǐng)求是并發(fā)的,可能在短時(shí)間內(nèi)大量請(qǐng)求進(jìn)入系統(tǒng),不同請(qǐng)求的traceId不同,每經(jīng)過(guò)不同的應(yīng)用服務(wù)后,都會(huì)產(chǎn)生相應(yīng)的日志并存入日志文件,這樣就造成同一個(gè)traceId下日志中間會(huì)存在各個(gè)不一樣的traceId的請(qǐng)求調(diào)用到不同應(yīng)用產(chǎn)生的日志,同一個(gè)traceId不同應(yīng)用服務(wù)的日志將不會(huì)連續(xù)。
所以,為了把相同traceId的請(qǐng)求日志區(qū)分出來(lái),引入了日志數(shù)據(jù)存入數(shù)據(jù)結(jié)構(gòu):Map<stringLLinkedList<string>>。其中,Map里的key=traceId,Map里的va1ue=LinkedList<string>,LinkedList為有序列表,LinkedList的每條數(shù)據(jù)為該日志信息。
2.3提取異常日志traceld
一個(gè)穩(wěn)定的系統(tǒng),業(yè)務(wù)辦理的成功率都在99.99%以上,這些業(yè)務(wù)成功辦理的日志信息對(duì)于極少數(shù)業(yè)務(wù)辦理失敗的原因排查無(wú)關(guān)緊要,最重要的是業(yè)務(wù)辦理時(shí)出現(xiàn)的問(wèn)題信息,需要通過(guò)暴露出來(lái)的異常信息進(jìn)行排查,才能解決存在的問(wèn)題。
然而,為了區(qū)分正常和異常的日志,需要把重要的異常日志從大量的日志信息中提取出來(lái)。通過(guò)判斷讀取出來(lái)的日志信息,判斷該日志信息的狀態(tài)是否為200,如果為非200,那么該日志為異常日志,需要把該日志所在讀取的批次setId和該日志的traceId記錄到錯(cuò)慢日志集合,并用Map<stringLList<string>>存儲(chǔ),其中,Map里的key=setId,Map里的value=traceId。
2.4計(jì)算
通過(guò)上述三個(gè)步驟,完成對(duì)日志流數(shù)據(jù)的實(shí)時(shí)按批次讀取和按批次存儲(chǔ),把識(shí)別到的異常日志對(duì)應(yīng)的traceId提取出來(lái),并使用集合方式存儲(chǔ)起來(lái)。
以異常集合的traceId為出發(fā)點(diǎn),從暫存的數(shù)據(jù)中提取出涉及該鏈路的所有節(jié)點(diǎn)日志數(shù)據(jù)。由于日志數(shù)據(jù)是按批次讀取的,所以異常日志traceId也是按集合批次進(jìn)行存儲(chǔ)區(qū)分。但落在當(dāng)前setId集合里的鏈路日志,可能存在該鏈路數(shù)據(jù)落在相鄰的setId集合里,為了確保囊括該請(qǐng)求鏈路所有節(jié)點(diǎn)的日志數(shù)據(jù),需要把setId集合的前后兩個(gè)setId集合對(duì)應(yīng)traceId提取出來(lái)。
所以,計(jì)算setId=n的日志數(shù)據(jù)時(shí),需2.3點(diǎn)提到的集合(n-l,n,n+l)esetId,并從2.2的traceId集合里獲取key值一致的traceId所對(duì)應(yīng)的List<string>數(shù)據(jù)。
3實(shí)驗(yàn)
采用日志大小為4GB的日志服務(wù)器作為日志流輸出口,異常日志采集服務(wù)器分類4G內(nèi)存。通過(guò)上述方法對(duì)日志流數(shù)據(jù)進(jìn)行異常日志鏈路采集。通過(guò)對(duì)日志流輸出進(jìn)行調(diào)整,測(cè)試采用上述方法在不同日志流輸出速率下的異常鏈路采集時(shí)長(zhǎng)。
設(shè)定日志流速率在700~1650MB/s范圍內(nèi),日志流速率間隔為50MB/s,調(diào)整日志流速率,日志采集時(shí)長(zhǎng)/日志流時(shí)長(zhǎng)、異常日志查全率統(tǒng)計(jì)如圖2所示。當(dāng)日志流速率在1200~1300MB/s時(shí),采集時(shí)長(zhǎng)和日志流時(shí)長(zhǎng)的比值大于1,表明采集時(shí)間比日志流時(shí)間長(zhǎng),并且隨著日志流速率提高,采集時(shí)間與日志流時(shí)長(zhǎng)比值增大,那么異常日志采集最高速率在1200~1300MB/s為宜。
為了更精確地獲取異常日志采集速率,設(shè)定日志流速率在ll50~1340MB/s范圍內(nèi),日志流速率間隔為10MB/s,調(diào)整日志流速率,日志采集時(shí)長(zhǎng)/日志流時(shí)長(zhǎng)、異常日志查全率統(tǒng)計(jì)如圖3所示。當(dāng)日志流速率大于1260MB/s時(shí),采集時(shí)長(zhǎng)和日志流時(shí)長(zhǎng)的比值大于1,如表1所示,表明采集速率達(dá)到最大值。
4結(jié)果與討論
當(dāng)日志流速率在1260MB/s以下時(shí),采集時(shí)間與日志流時(shí)間一致:當(dāng)日志流速率在1260MB/s以上時(shí),采集時(shí)間比日志流時(shí)間長(zhǎng),并且隨著日志流速率提高,采集時(shí)長(zhǎng)與日志流時(shí)長(zhǎng)比值增大。數(shù)據(jù)表明,采集速率達(dá)到1260MB/s,日志流速率在1260MB/s以內(nèi)時(shí)能實(shí)時(shí)處理日志信息。
5結(jié)語(yǔ)
本文旨在分析分布式系統(tǒng)鏈路日志的現(xiàn)況,提出了一種分布式鏈路異常日志采集的方法:只要請(qǐng)求的鏈路跟蹤數(shù)據(jù)存在異常節(jié)點(diǎn),那么該異常節(jié)點(diǎn)涉及的全鏈路數(shù)據(jù)將被采集。通過(guò)該方法,分布式鏈路異常日志采集速率達(dá)到了1260MB/s,查全率達(dá)到100%。該方法大幅提升了業(yè)務(wù)高峰期系統(tǒng)故障問(wèn)題定位的效率,提高了系統(tǒng)故障處理能力和業(yè)務(wù)辦理質(zhì)量,提升了客戶滿意度。