的輸入,檢查 輸出和預(yù)期是否相符。它的輸出可以從DB等各種渠道獲取,即使在非自動化場景下,也可 以用肉眼檢查輸出內(nèi)容。線上SOA環(huán)境可以模仿線下單機(jī)環(huán)境的檢測方法,因此,需要找到 自己的輸入和輸出。如圖3所示,輸入包括用戶的操作,例如瀏覽網(wǎng)頁、提交表單等,也可能 包括系統(tǒng)行為,例如淘寶調(diào)用支付寶進(jìn)行付款操作,則在入口處記錄下日志即第一日志,從 第一日志中提出數(shù)據(jù)作為輸入數(shù)據(jù);另外,在第二業(yè)務(wù)結(jié)束后輸出第二日志,從第二日志中 提出數(shù)據(jù)作為輸出數(shù)據(jù)。
[0048] 其中,第一日志和第二日志的粒度相同。從第二日志中提取出輸入數(shù)據(jù)可以為:根 據(jù)第二日志獲得匹配的第二日志模型,使用第二日志模型從第二日志中提取出輸入數(shù)據(jù), 其中,該第二日志模型包括解析規(guī)則,還可以包括解析權(quán)限等信息。
[0049] S203,將輸入數(shù)據(jù)和輸出數(shù)據(jù)進(jìn)行比對,定位出發(fā)生故障的業(yè)務(wù)。
[0050] 找到輸入數(shù)據(jù)和輸出數(shù)據(jù)后就可以進(jìn)行分析統(tǒng)計,輸出如圖4所示的報表,通過 該報表即可推斷業(yè)務(wù)是否正常。
[0051] 具體地,報表中曲線a代表用戶的輸入,曲線b代表業(yè)務(wù)輸出,用戶的輸入即可理 解為"輸入數(shù)據(jù)",例如,在某個時刻有1000個用戶提交了 "下單"表單,那在一切正常的情 況下就應(yīng)該產(chǎn)出1000筆下單業(yè)務(wù),圖4中箭頭所指位置很可能發(fā)生異常,因?yàn)橛脩舻男袨?(輸入)在增多,而成功的業(yè)務(wù)(輸出)卻有所下降,這可能預(yù)示著某些用戶經(jīng)過多次重試 才完成操作。
[0052] 然而,隨著業(yè)務(wù)的日趨復(fù)雜,很難保證第一日志和第二日志完全一一匹配,具體原 因是:SOA業(yè)務(wù)的特點(diǎn)是下游業(yè)務(wù)穩(wěn)態(tài)、通用,上游業(yè)務(wù)靈活應(yīng)變,再加上日志本身就不嚴(yán) 謹(jǐn),輸入輸出很難保證嚴(yán)格匹配。而且讓檢測人員花費(fèi)巨大的精力去梳理錯綜復(fù)雜的業(yè)務(wù) 鏈路,找到每種業(yè)務(wù)的入口和出口也是一項(xiàng)繁重的工作,尤其是那些正處于發(fā)展階段、變更 頻繁的業(yè)務(wù),更是如此。
[0053] 所以,一個改進(jìn)的方案就是放棄"輸入數(shù)據(jù)",只在下游業(yè)務(wù)覆蓋出口處的日志 (越下游越穩(wěn)態(tài)),即只需要第二日志的數(shù)據(jù)。然后對它們的歷史數(shù)據(jù)做線性回歸,預(yù)測未 來的數(shù)值(作為預(yù)期輸出),再與實(shí)際輸出進(jìn)行對比,定位出發(fā)生故障的業(yè)務(wù)。具體地,獲 得第二業(yè)務(wù)在當(dāng)前時間的當(dāng)前第二日志,從當(dāng)前第二日志中提取出實(shí)際輸出;獲得第二業(yè) 務(wù)自當(dāng)前時間起預(yù)定時間段內(nèi)的歷史第二日志,從歷史第二日志中提取出數(shù)據(jù),對提取出 的數(shù)據(jù)進(jìn)行線性回歸處理,將處理結(jié)果作為預(yù)期輸出,若預(yù)期輸出和實(shí)際輸出一致,則無故 障,若二者不一致,則位于該業(yè)務(wù)鏈上的業(yè)務(wù)均有故障。其中,上述預(yù)定時間段可根據(jù)需要 動態(tài)調(diào)整,例如可以為3周-8周,優(yōu)選地為5周,還可以為其他數(shù)值。例如,獲得A業(yè)務(wù)在 今天的業(yè)務(wù)量為10000 ;獲得A業(yè)務(wù)過去五周的業(yè)務(wù)量,對過去五周的業(yè)務(wù)量做線性回歸, 獲得預(yù)期業(yè)務(wù)量為10000 ;二者一致,則確定A業(yè)務(wù)正常。
[0054] 如圖5所示,曲線c是實(shí)際輸出業(yè)務(wù)量,曲線d是根據(jù)歷史數(shù)據(jù)做線性回歸預(yù)測的 量(俗稱基線,預(yù)期輸出)。這種解決方案比較適合有規(guī)律的業(yè)務(wù)(比如電子商務(wù)的交易 量,是一種與用戶作息規(guī)律匹配的穩(wěn)態(tài)曲線,白天量大、夜里量少)。在實(shí)際場景中,絕大部 分業(yè)務(wù)都是有規(guī)律的(比如"打車軟件"在接近上下班高峰期時業(yè)務(wù)量會明顯上漲)。規(guī)律 不明顯的業(yè)務(wù)主要有兩種,一種是"成長中"的業(yè)務(wù),用戶剛剛開始接觸,還沒有形成穩(wěn)態(tài)的 用戶群體和使用習(xí)慣,甚至業(yè)務(wù)量極少,不適合作為線性回歸算法的輸入;另一種是非用戶 行為,比如系統(tǒng)自動執(zhí)行的后臺任務(wù)。對于這種少數(shù)場景,可以有針對性的用閾值、分時間 段檢測等方案來彌補(bǔ)。
[0055] 至此,我們已經(jīng)可以證明利用日志能夠在線上SOA生產(chǎn)環(huán)境中實(shí)現(xiàn)和線下單元測 試接近的檢測效果,隨著業(yè)務(wù)點(diǎn)覆蓋的全面,就越能保障絕大部分故障都能夠被及時有效 的發(fā)現(xiàn)。至于工作量,其實(shí)等量于上文多次提到的測試用例。理論上,回歸測試時的用例其 實(shí)就是要覆蓋所有的業(yè)務(wù)點(diǎn),甚至是一一對應(yīng)的關(guān)系。所以理想場景下,有N個回歸測試用 例,就應(yīng)該有N個對應(yīng)的業(yè)務(wù)點(diǎn)需要覆蓋監(jiān)控。
[0056] 本申請實(shí)施例在定位出發(fā)生故障的業(yè)務(wù)之后,還需要確定故障原因,如圖6所示, 確定故障原因的過程包括:
[0057] S601,自動獲取每個發(fā)生故障的業(yè)務(wù)的調(diào)試日志。
[0058] 其中,自動獲取每個發(fā)生故障的業(yè)務(wù)的調(diào)試日志包括:自動獲取每個發(fā)生故障的 業(yè)務(wù)所包含的服務(wù)器的調(diào)試日志,該調(diào)試日志的粒度小于上述第一日志和第二日志的粒 度。
[0059] S602,對自動獲取的所有調(diào)試日志進(jìn)行聚合處理,定位出故障原因。
[0060] 對調(diào)試日志進(jìn)行聚合處理,可以確定發(fā)生故障的服務(wù)器,另外,可以獲得對應(yīng)每個 發(fā)生故障的業(yè)務(wù)的日志分析結(jié)果,對日志分析結(jié)果進(jìn)行聚合遞歸分析,確定出故障源,即確 定出真正發(fā)生故障的業(yè)務(wù)。
[0061] 通常情況下,線下單機(jī)環(huán)境通過debug可以非常輕松地發(fā)現(xiàn)故障原因,那是因?yàn)?在debug時可以跟隨每一行代碼逐步運(yùn)行,能夠檢查每一行代碼的輸入和輸出是否符合預(yù) 期,比如調(diào)用一個函數(shù)時,可以在debug過程中檢查傳入的參數(shù)是否符合預(yù)期,函數(shù)的返回 值是否符合預(yù)期,以此來定位故障是否發(fā)生在函數(shù)內(nèi)部。
[0062] 為了達(dá)到接近于debug的效果,在本實(shí)施例中,可以模仿線下的debug過程,例如, 可以在每個函數(shù)的開始位置用日志輸出它接收到的參數(shù)內(nèi)容,在結(jié)束位置用日志輸出對應(yīng) 函數(shù)返回的結(jié)果,通過檢查日志,可以定位到哪個函數(shù)出現(xiàn)了問題。
[0063] 具體地,以以下一段代碼為例描述通過日志定位故障原因的過程:
[0064]
[0066] 上述代碼的日志輸出結(jié)果為:
[0067] add函數(shù)調(diào)用開始,參數(shù):[3, 4]
[0068] add函數(shù)調(diào)用結(jié)束,result = 7
[0069] square函數(shù)調(diào)用開始,參數(shù):[7]
[0070] square 函數(shù)調(diào)用結(jié)束,result = 14
[0071] 需要說明的是,上述內(nèi)容僅為日志的部分內(nèi)容,通過對輸入?yún)?shù)[7]和輸出 result = [14]的檢查,可以定位出bug出現(xiàn)在square函數(shù)的調(diào)用環(huán)節(jié),雖然該定位過程不 如debug方便直觀,但是日志中的信息也足夠定位出故障。并且,這種日志記錄的粒度越細(xì) (即粒度由粗到細(xì)依次為:系統(tǒng)〉模塊〉函數(shù)〉代碼),能夠定位的異常點(diǎn)就越準(zhǔn)確(在一 個函數(shù)內(nèi)部還可以將代碼分為多個部分(part),通過檢查每個part的輸入和輸出,就能確 定每個part是否出現(xiàn)異常),分析的難度也就越大(日志量太大)。
[0072] 另外,在現(xiàn)實(shí)的場景中,還可以提供debug日志開關(guān)機(jī)制,即設(shè)置輸出調(diào)試日志的 開關(guān)按鈕,以開啟或關(guān)閉輸出調(diào)試日志的功能。具體地,在特殊情況下需要動態(tài)控制線上是 否輸出細(xì)粒度的debug日志,以用于排查故障原因(平常情況下為了避免輸出過多的日志 而關(guān)閉)。Log4j等日志框架也都提供了 debug輸出模式。
[0073] 如果能將人工在單機(jī)上的分析過程翻譯為程序?qū)兹f臺機(jī)器的自動化分析過程, 即將人工分析的過程轉(zhuǎn)換為自動分析的過程,可以大大提高處理的效率,并且實(shí)現(xiàn)并不難 (就是通過各種匹配規(guī)則、統(tǒng)計規(guī)則、關(guān)聯(lián)規(guī)則來實(shí)現(xiàn)),然后,對單機(jī)分析結(jié)果進(jìn)行聚合, 就可以定位出故障原因。
[0074] 如圖7所示,A1、A2、A3代表集群系統(tǒng)A的各臺服務(wù)器,A、B、C是SOA環(huán)境里的三 個集群系統(tǒng)。對單機(jī)分析結(jié)果的聚合最常發(fā)生在以下兩個場景:
[0075] 1)將服務(wù)器的分析結(jié)果聚合為集群系統(tǒng)的分析結(jié)果
[0076] 對集群系統(tǒng)內(nèi)各臺服務(wù)器的聚合,其實(shí)就是對單機(jī)的分析結(jié)果進(jìn)行匯總統(tǒng)計,t匕 如匯總得到:
[0077] AU A2、A3三個服務(wù)器上通過日志都推斷出目前的故障模塊是在調(diào)用M函數(shù)時發(fā) 生異常(M函數(shù)十分可能是故障源,假如M函數(shù)都是在訪問某個分布式緩存,那么分布式緩 存的嫌疑就很大);或者
[0078] AU A2日志分析結(jié)果一切正常,但是A3的N函數(shù)處發(fā)生異常(N函數(shù)可能是故障 發(fā)生點(diǎn),但也有可能僅僅是A3這臺機(jī)器的單機(jī)現(xiàn)象,比如分布式緩存沒有問題,但是A3單 機(jī)的網(wǎng)絡(luò)連接斷開了)。
[0079] 2)將各個集群系統(tǒng)(簡稱集群)的分析結(jié)果聚合為整個鏈路、甚至整個SOA環(huán)境 的分析結(jié)果
[0080] 集群之間的聚合其實(shí)就是結(jié)合集群之間的服務(wù)依賴關(guān)系,遞歸的處理整個鏈路的 日志分析結(jié)果。
[0081] 比如A的分析結(jié)果是在調(diào)用XXX函數(shù)時異常,XXX函數(shù)是調(diào)用B系統(tǒng)的yyy服務(wù); B的分析結(jié)果是在自身yyy服務(wù)處理中發(fā)生異常,而異常發(fā)生的環(huán)節(jié)是調(diào)用C系統(tǒng)的zzz服 務(wù);C的分析結(jié)果是在自身 ZZZ服務(wù)處理中發(fā)生異常,異常發(fā)生的環(huán)節(jié)是執(zhí)行某個結(jié)構(gòu)化查 詢語言(SQL)語句時獲取不到數(shù)據(jù)源連接(connection);于是大致推斷C系統(tǒng)與DB之間 的connection有問題,接下來需要詳細(xì)檢查DB當(dāng)前的各項(xiàng)指標(biāo)、C系統(tǒng)的數(shù)據(jù)源配置是否 正常等等,而系統(tǒng)A和B僅僅是受害者,即系統(tǒng)A和B因調(diào)用C,故出現(xiàn)故障。
[0082] 上述方式雖然可以定位出故障原因,但在實(shí)現(xiàn)的過程中會存在兩個問題:首先是 日志量過大造成的輸入或輸出(I/O)性能損耗;其次是各系統(tǒng)不一定都能嚴(yán)格遵循日志 規(guī)范,尤其在大型SOA環(huán)境中,經(jīng)常會出現(xiàn)日志的不規(guī)范、不合理、不輸出,導(dǎo)致排查線索缺 失。
[0083] 針對第一個問題,本申請實(shí)施例可以通過日志框架(中間件)代為執(zhí)行通用的日 志輸出,以降低I/O性能損耗。日志框架能夠覆蓋的環(huán)節(jié)包括:跨系統(tǒng)RPC服務(wù)調(diào)用、消息收 發(fā)、訪問DB、訪問緩存等。這些環(huán)節(jié)已經(jīng)足夠定位到粗粒度的故障源;而且