從傳統(tǒng)服務(wù)鏈監(jiān)控到端到端流程監(jiān)控技術(shù)實(shí)現(xiàn)
今天談下服務(wù)鏈監(jiān)控和端到端流程監(jiān)控。對(duì)于服務(wù)鏈監(jiān)控有開源的類似zipkin,skywalking開源工具可以實(shí)現(xiàn)完整的服務(wù)鏈監(jiān)控功能,但是采用這些工具的一般都需要在JVM啟動(dòng)的時(shí)候注入探針Jar包,進(jìn)行訪問攔截。而本方法則是一個(gè)自己規(guī)約實(shí)現(xiàn)服務(wù)鏈監(jiān)控,整體的思路和方法實(shí)際和我們常說的服務(wù)鏈監(jiān)控是一致的。
服務(wù)鏈監(jiān)控實(shí)現(xiàn)
SkyWalking監(jiān)控圖
服務(wù)鏈監(jiān)控基本概念與場(chǎng)景說明
服務(wù)鏈監(jiān)控APM(Application Performance Management)即應(yīng)用性能管理,屬于IT運(yùn)維管理(ITOM)范疇。主要是針對(duì)企業(yè)關(guān)鍵業(yè)務(wù)的IT應(yīng)用性能和用戶體驗(yàn)的監(jiān)測(cè)、優(yōu)化,提高企業(yè)IT應(yīng)用的可靠性和質(zhì)量,保證用戶得到良好的服務(wù),降低IT總擁有成本(TCO)。
在網(wǎng)絡(luò)環(huán)境下,一次獨(dú)立的服務(wù)請(qǐng)求往往需要涉及到多個(gè)服務(wù)。由于應(yīng)用或服務(wù)構(gòu)建在不同的軟件模塊上,這些軟件模塊,有可能是由不同的團(tuán)隊(duì)開發(fā)、使用不同的編程語言來實(shí)現(xiàn),而且有可能部署在不同的硬件環(huán)境中,橫跨多個(gè)不同的數(shù)據(jù)中心。因此,就需要一些可以幫助理解系統(tǒng)行為、用于分析性能問題的工具,以便發(fā)生故障的時(shí)候,能夠快速定位和解決問題。
服務(wù)鏈監(jiān)控是通常應(yīng)用于APM,即將實(shí)際應(yīng)用性能和相關(guān)服務(wù)的調(diào)用關(guān)系以服務(wù)鏈方式串聯(lián)起來,以便分析和定位實(shí)際影響到最終應(yīng)用性能的關(guān)鍵服務(wù),并進(jìn)行后續(xù)處理。
分布式環(huán)境下的服務(wù)鏈監(jiān)控基本模型如下:
圖片
其中,在上圖中有幾個(gè)比較重要的概念。
- Span:基本工作單元,一次鏈路調(diào)用創(chuàng)建一個(gè)span,通過一個(gè)XX位ID標(biāo)識(shí)它,一般是UUID較為方便。當(dāng)然,Span中還可以有其他的數(shù)據(jù),例如描述信息、時(shí)間戳等。
- Trace:類似于樹結(jié)構(gòu)的Span集合,表示一條調(diào)用鏈路,存在唯一標(biāo)識(shí)。
服務(wù)鏈監(jiān)控場(chǎng)景說明
如果需要在復(fù)雜的網(wǎng)絡(luò)環(huán)境上下文中理解分布式系統(tǒng)的行為,就需要監(jiān)控那些橫跨了不同的應(yīng)用、不同的服務(wù)器之間的關(guān)聯(lián)動(dòng)作。在多系統(tǒng)、多模塊、多服務(wù)構(gòu)成的架構(gòu)系統(tǒng)中,幾乎每一個(gè)前端請(qǐng)求都會(huì)形成一個(gè)復(fù)雜的分布式服務(wù)調(diào)用鏈路。
一個(gè)服務(wù)請(qǐng)求的完整調(diào)用鏈路可能如下圖所示:
圖片
即在前臺(tái)功能頁面,點(diǎn)擊提交單據(jù)按鈕的時(shí)候,需要調(diào)用業(yè)務(wù)內(nèi)部多個(gè)服務(wù)接口,同時(shí)也需要調(diào)用到外部系統(tǒng)提交的服務(wù)接口,實(shí)現(xiàn)完整的業(yè)務(wù)功能邏輯。那就需要對(duì)整個(gè)服務(wù)調(diào)用鏈進(jìn)行監(jiān)控。
那么,在業(yè)務(wù)規(guī)模不斷增大、服務(wù)不斷增多以及頻繁變更的情況下,面對(duì)復(fù)雜的調(diào)用鏈路就帶來一系列問題:
- 如何快速發(fā)現(xiàn)問題?
- 如何判斷故障影響范圍?
- 如何梳理服務(wù)依賴以及依賴的合理性?
- 如何分析鏈路性能問題以及實(shí)時(shí)容量規(guī)劃?
有了服務(wù)鏈監(jiān)控,我們能夠做到:
- 提供鏈路追蹤,故障快速定位:可以通過結(jié)合業(yè)務(wù)日志快速定位錯(cuò)誤信息。
- 可視化:各個(gè)階段耗時(shí),進(jìn)行性能分析。
- 依賴優(yōu)化:各個(gè)調(diào)用環(huán)節(jié)的可用性、梳理服務(wù)依賴關(guān)系以及優(yōu)化。
- 數(shù)據(jù)分析,優(yōu)化鏈路:可以得到用戶的行為路徑,匯總分析應(yīng)用在很多業(yè)務(wù)場(chǎng)景。
業(yè)務(wù)場(chǎng)景驗(yàn)證和關(guān)鍵技術(shù)實(shí)現(xiàn)
在這里,我們舉一個(gè)業(yè)務(wù)報(bào)賬單單據(jù)提交功能來進(jìn)行說明和驗(yàn)證。業(yè)務(wù)人員在報(bào)賬平臺(tái)填寫報(bào)賬申請(qǐng)單,填寫完成后進(jìn)行提交,具體涉及到如下操作步驟。
- 進(jìn)行數(shù)據(jù)完整性校驗(yàn)(調(diào)用供應(yīng)商有效性校驗(yàn)接口,調(diào)用賬戶有效性校驗(yàn)服務(wù))
- 調(diào)用預(yù)算校驗(yàn)和扣減(調(diào)用預(yù)算校驗(yàn)服務(wù),調(diào)用預(yù)算扣減子服務(wù))
- 調(diào)用申請(qǐng)單保存服務(wù),進(jìn)行申請(qǐng)單保存
- 調(diào)用工作流平臺(tái)提供的工作流啟動(dòng)服務(wù)接口進(jìn)行流程啟動(dòng)
圖片
服務(wù)鏈監(jiān)控的使用規(guī)范
a.在接口服務(wù)調(diào)用中增加TRACE_ID信息
需要在接口服務(wù)調(diào)用的輸入中增加TRACE_ID字段,作為服務(wù)鏈跟蹤使用。
b. TRACE_ID組成說明
一個(gè)用于服務(wù)鏈監(jiān)控的TRACE_ID的生成,由以下信息所構(gòu)成。
概述:UUID+ SPANID +SPANID+SPANID 組成
說明:UUID為每一個(gè)服務(wù)調(diào)用鏈,生成一個(gè)獨(dú)立唯一的UUID值
SPANID:SPANID為01、02順序編碼,服務(wù)調(diào)用每進(jìn)一層增,即增加一層SPANID
圖片
依據(jù)上述規(guī)則,生成的一個(gè)參考如下:
TRACE_ID:550e8400-e29b-41d4-a716-446655440000.01.01.02
c. 服務(wù)鏈監(jiān)控參考實(shí)現(xiàn)偽代碼
根據(jù)前述業(yè)務(wù)場(chǎng)景例證的說明,下面以報(bào)賬服務(wù)的調(diào)用鏈路來說明,如何使用TRACE_ID來進(jìn)行服務(wù)鏈的監(jiān)控。
1. 業(yè)務(wù)系統(tǒng)所有的子方法調(diào)用都需要增加TRACE_ID參數(shù)進(jìn)行傳遞,子方法調(diào)用下一級(jí)子方法的時(shí)候生成新的TRACE_ID值,即TRACE_ID的定義是遞歸的。
TRACE_ID = TRACE_ID + SPANID
2. SPANID按服務(wù)調(diào)用的順序進(jìn)行兩位編碼,每次步長(zhǎng)增加1,諸如01、02、 …. 99
參考下述偽代碼,描述了前述的監(jiān)控實(shí)現(xiàn)過程:
public String ApplySubmit()
{
//通過工具類生成UUID
String uuid = utils.generateUUID();
//調(diào)用數(shù)據(jù)檢查服務(wù),通過UUID + SPANID 拼接出每次服務(wù)請(qǐng)求的TraceID
Boolean r1 = this.DataValidateSrv(params, uuid + ”.01”);
//調(diào)用預(yù)算檢查服務(wù)
Boolean r2 = this.BudgetValidateSrv(params, uuid + “.02”);
//調(diào)用單據(jù)保存服務(wù)
Boolean r3 = this.BillSaveSrv(params, uuid + “.03”);
//調(diào)用啟動(dòng)工作流服務(wù)
Boolean r4 = this.StartWorkFlow(params, uuid + “.04”);
//結(jié)果返回處理
String result;
return result;
}
對(duì)于需要進(jìn)行跟蹤的下一級(jí)服務(wù),也需要依照同樣的原則進(jìn)行處理:
public String DataValidateSrv(params, TraceID)
{
//調(diào)用供應(yīng)商檢查服務(wù),通過TRACEID + SPANID 拼接出每次服務(wù)請(qǐng)求的TraceID
this.VendorValidateSrv(params, TraceID + ”.01”);
//調(diào)用銀行賬戶檢查服務(wù)
this.BankAccountValidateSrv(params, TraceID + “.02”);
//結(jié)果返回處理
String result;
///
return result;
}
d.監(jiān)控日志的記錄
由于在前臺(tái)操作觸發(fā)的后臺(tái)服務(wù)調(diào)用操作中,有可能調(diào)用注冊(cè)在集成平臺(tái)上的服務(wù),也可以調(diào)用業(yè)務(wù)系統(tǒng)內(nèi)部的服務(wù)接口,因此,要做到全面的服務(wù)鏈監(jiān)控需要對(duì)兩部分的日志都進(jìn)行記錄。
- ESB總線服務(wù):平臺(tái)會(huì)記錄服務(wù)日志,調(diào)用時(shí)間消耗;業(yè)務(wù)系統(tǒng)也可以同時(shí)記錄。
- 業(yè)務(wù)系統(tǒng)內(nèi)部服務(wù):集成平臺(tái)無法記錄,必須由業(yè)務(wù)系統(tǒng)自己記錄。
服務(wù)日志需要同時(shí)記錄服務(wù)調(diào)用時(shí)間消耗、服務(wù)ID、服務(wù)名稱、TRACE_ID、輸入、輸出信息。具體代碼參考如下:
//數(shù)據(jù)檢查服務(wù)方法
Void DataValidSrv(params, TRACE_ID);
{
//獲取開始時(shí)間
Time StartTime = System.GetCurrentTime();
//獲取入口參數(shù)
Map inputParams = this.method.getParams();
//供應(yīng)商檢查,實(shí)際為UUID.01.01
this.VendorValidSrv(params,TRACE_ID.01);
//銀行賬戶檢查
this.BankValidSrv(params,TRACE_ID.02);
Map outPutParamorData = this.method.getOutPutParams();
Time EndTime = System.GetCurrentTime();
LogSericeData(ServiceID, ‘DataValidSrv’, StartTime , EndTime, inputParams, outPutParams);
}
注:業(yè)務(wù)系統(tǒng)也可以采用類似AOP模式進(jìn)行調(diào)用信息攔截后統(tǒng)一記錄。
服務(wù)鏈監(jiān)控的展示
圖片
對(duì)于服務(wù)鏈監(jiān)控,集成平臺(tái)可以根據(jù)記錄的TRACE_ID信息進(jìn)行關(guān)聯(lián),形成服務(wù)鏈展示樹,業(yè)務(wù)系統(tǒng)提供UUID值,即可以查看到完整的服務(wù)調(diào)用鏈,并看到每個(gè)服務(wù)實(shí)例調(diào)用的時(shí)間。當(dāng)然,對(duì)于服務(wù)鏈監(jiān)控仍然可以參考上篇博文中談到的進(jìn)行可視化的圖形樹狀結(jié)構(gòu)展示。
當(dāng)前為了展示方便,主流的服務(wù)鏈監(jiān)控基本都是參與表格+樹狀展開的模式進(jìn)行展示。
端到端流程監(jiān)控
基于接口的跨系統(tǒng)流程概述
在這里的端到端流程監(jiān)控特指跨系統(tǒng)交互業(yè)務(wù)流程,即一個(gè)完整的端到端流程跨越多個(gè)系統(tǒng),多個(gè)系統(tǒng)之間通過接口交互來實(shí)現(xiàn)協(xié)同。一個(gè)完整的端到端流程如下:
圖片
如上圖,一個(gè)完整的企業(yè)內(nèi)部自建電商平臺(tái),在完成一個(gè)B端客戶的訂單下達(dá),執(zhí)行和交付的時(shí)候,需要跨越電商平臺(tái),CRM系統(tǒng),物流平臺(tái),SAP-ERP系統(tǒng)和第三方支付平臺(tái),第三方的物流平臺(tái)來共同完成。
那么在下達(dá)一個(gè)訂單后,當(dāng)前的流程究竟走到了哪里?是否已經(jīng)完成支付,訂單是否已經(jīng)傳遞到ERP系統(tǒng),訂單是否已經(jīng)安排配送,訂單當(dāng)前的物流配送是否完成,訂單是否已經(jīng)被客戶簽收等,整合是上面端到端流程里面的關(guān)鍵接口交互點(diǎn)。
即:如果一個(gè)接口點(diǎn)正常執(zhí)行完,那么說明業(yè)務(wù)流已經(jīng)走到下個(gè)階段。
而對(duì)于類似上圖的跨多個(gè)系統(tǒng)的端到端流程,我們往往希望跟蹤一個(gè)訂單當(dāng)前執(zhí)行到哪個(gè)階段,具體什么狀態(tài),那么核心的關(guān)鍵字就是訂單編號(hào),可以看到后續(xù)的支付,物流,配送,訂單執(zhí)行等相關(guān)接口,接口的輸入信息中都會(huì)有訂單編號(hào)這個(gè)關(guān)鍵字。
跨系統(tǒng)交互流程建模
可視化接口交互流程設(shè)計(jì)
從前面分析可以看到,可以通過接口交互分析來倒推流程。因此我們可以對(duì)接口交互流程進(jìn)行可視化設(shè)計(jì)和建模。同時(shí)對(duì)所有的接入注冊(cè)到ESB服務(wù)總線進(jìn)行管理。
由于接口服務(wù)都通過ESB服務(wù)總線進(jìn)行封裝代理后接入,因此理論上說從實(shí)際業(yè)務(wù)服務(wù)調(diào)用實(shí)例數(shù)據(jù)和日志中是可以反推出來端到端的業(yè)務(wù)流程的,也就是可以通過服務(wù)實(shí)例和服務(wù)鏈的監(jiān)控來間接的監(jiān)控跨系統(tǒng)的業(yè)務(wù)流轉(zhuǎn)是否正常。
簡(jiǎn)單來說,比如一個(gè)采購(gòu)訂單,基于一個(gè)采購(gòu)訂單號(hào),我們實(shí)際上可以通過服務(wù)監(jiān)控?cái)?shù)據(jù)來分析到該訂單是否已經(jīng)從采購(gòu)系統(tǒng)導(dǎo)入到ERP,是否已經(jīng)進(jìn)行了報(bào)賬申請(qǐng),是否已經(jīng)進(jìn)行了付款等,實(shí)際上這些信息從服務(wù)實(shí)例日志中都可以提取出來。
要完成這件事情,實(shí)際上有兩個(gè)關(guān)鍵點(diǎn)要做,即首先要對(duì)服務(wù)鏈本身進(jìn)行進(jìn)行服務(wù)鏈流程建模,其次是能夠?qū)Σ杉娜罩镜妮斎胼敵鲋心軌蜃ト〕鼋Y(jié)構(gòu)化的關(guān)鍵業(yè)務(wù)字段信息。只要做到這兩點(diǎn),我們就很容易實(shí)現(xiàn)可視化的跨系統(tǒng)服務(wù)鏈監(jiān)控功能。
在前面我們做ESB服務(wù)設(shè)計(jì)器的時(shí)候,已經(jīng)已經(jīng)剝離了原流程引擎中進(jìn)行服務(wù)編排或可視化流程建模的能力。實(shí)際上這里的設(shè)計(jì)本身也就是一個(gè)多個(gè)服務(wù)編排設(shè)計(jì)的過程,將多個(gè)服務(wù)編排設(shè)計(jì)到一起。注意在這個(gè)過程中還需要允許有分支,也允許并行。服務(wù)鏈監(jiān)控最終形成的也是一個(gè)完整的服務(wù)鏈監(jiān)控樹。只是這個(gè)監(jiān)控樹的形成是通過可視化的服務(wù)組合編排工具來實(shí)現(xiàn)的而已。
針對(duì)不同的跨系統(tǒng)業(yè)務(wù)監(jiān)控,都需要針對(duì)不同場(chǎng)景設(shè)計(jì)不同的服務(wù)監(jiān)控模型。
比如現(xiàn)在設(shè)計(jì)一個(gè)采購(gòu)訂單服務(wù)鏈監(jiān)控模型,我們可以對(duì)該模型進(jìn)行簡(jiǎn)化,具體如下通過建模工具形成如下模型樹。合同導(dǎo)入服務(wù)-》采購(gòu)訂單導(dǎo)入服務(wù)-》采購(gòu)接收服務(wù)-》報(bào)賬申請(qǐng)服務(wù)-》應(yīng)付發(fā)票導(dǎo)入服務(wù)-》付款服務(wù)。
我們完全可以采用流程設(shè)計(jì)和建模工具來完成上圖的流程模型,當(dāng)然如果采用類似支持BPMN標(biāo)準(zhǔn)的流程建模工具還可以進(jìn)一步完成跨系統(tǒng)交互流程圖。
在這個(gè)跨系統(tǒng)交互流程圖中,銜接各個(gè)業(yè)務(wù)系統(tǒng)的仍然是相互之間的接口和服務(wù),我們?nèi)匀皇前凑找粋€(gè)核心單據(jù)為基本元素來進(jìn)行設(shè)計(jì),比如項(xiàng)目編號(hào),合同編號(hào),采購(gòu)訂單編號(hào)等。以這個(gè)編號(hào)來完成整個(gè)跨系統(tǒng)端到端流程的分析。
在建模的過程中,兩個(gè)系統(tǒng)間的連接線就是關(guān)鍵的接口服務(wù),但是由于不是直接的服務(wù)間的連接,因此仍然需要建立服務(wù)之間的關(guān)聯(lián)性。比如我們整體跨系統(tǒng)監(jiān)控都是以采購(gòu)訂單號(hào)來進(jìn)行跟蹤的話,我們就需要定義采購(gòu)訂單這個(gè)元素在每一個(gè)接口服務(wù)中對(duì)應(yīng)的XML-Element的位置,以確保這些服務(wù)之間本身能夠關(guān)聯(lián)起來。
整體我們看到實(shí)現(xiàn)的思路和服務(wù)鏈監(jiān)控基本相同。
仍然是先根據(jù)業(yè)務(wù)關(guān)鍵字查詢功能,精確查詢出相關(guān)的服務(wù)實(shí)例數(shù)據(jù)。然后將服務(wù)實(shí)例數(shù)據(jù)映射到流程圖上面,形成流程圖實(shí)例。對(duì)于已經(jīng)成功運(yùn)行的服務(wù)標(biāo)注為綠色,對(duì)于接口調(diào)用失敗的服務(wù)標(biāo)注為紅色,對(duì)于還沒有執(zhí)行到的服務(wù)標(biāo)注為灰色。
同時(shí)更加有意義的事情是,我們完全可以來動(dòng)畫效果模擬這個(gè)跨系統(tǒng)接口交互流程。即能夠動(dòng)態(tài)的看到各個(gè)接口被觸發(fā)和調(diào)用的前后順序。同時(shí)看到前后接口觸發(fā)的大致時(shí)間間隔信息。通過這種實(shí)現(xiàn)能夠很方便我們實(shí)現(xiàn)圍繞核心業(yè)務(wù)對(duì)象的端到端流程監(jiān)控能力。
當(dāng)然這是一種變通的端到端流程監(jiān)控實(shí)現(xiàn)思路,核心是先進(jìn)行流程建模,然后再通過業(yè)務(wù)關(guān)鍵字檢索功能動(dòng)態(tài)搜索匹配的服務(wù)日志調(diào)用數(shù)據(jù),再對(duì)流程圖進(jìn)行實(shí)例化解析。由于采用了Solr全文檢索能力,這個(gè)比我們完全自頂向下的來進(jìn)行端到端流程監(jiān)控實(shí)現(xiàn)更加高效。
業(yè)務(wù)日志采集和監(jiān)控查詢
圖片
在前面有篇文章我們專門談到過基于Solr進(jìn)行業(yè)務(wù)關(guān)鍵字查詢和報(bào)文日志全文檢索。而這個(gè)功能本身剛好用到服務(wù)鏈監(jiān)控里面。即我們不再需要對(duì)服務(wù)運(yùn)行報(bào)文數(shù)據(jù)全部進(jìn)行結(jié)構(gòu)化數(shù)據(jù),而只需要對(duì)這些數(shù)據(jù)建立元數(shù)據(jù)索引信息,有了索引后Solr基本就可以快速的檢索和定位到具體的服務(wù)。
對(duì)于當(dāng)前的服務(wù)日志,我們已經(jīng)完成了將Blob結(jié)構(gòu)的數(shù)據(jù)準(zhǔn)實(shí)時(shí)的采集并提取索引信息,進(jìn)入到Solr庫,實(shí)現(xiàn)了基于業(yè)務(wù)關(guān)鍵字的服務(wù)實(shí)例查詢能力,而原來我們只能基于服務(wù)實(shí)例號(hào)進(jìn)行服務(wù)日志的查詢。
基于Solr查詢速度相當(dāng)快,基本都是10多毫秒就能快速完成服務(wù)日志的檢索能力。在Solr實(shí)現(xiàn)了索引數(shù)據(jù)的創(chuàng)建,基于業(yè)務(wù)關(guān)鍵字的查詢能力后,接下來分析如何和服務(wù)鏈監(jiān)控進(jìn)行整合。
舉例來說,對(duì)于采購(gòu)訂單服務(wù)鏈監(jiān)控,進(jìn)入該功能后我們直接輸入采購(gòu)訂單號(hào),然后基于訂單號(hào)我們做如下事情。
- 首先找到采購(gòu)訂單服務(wù)鏈監(jiān)控流程模板,然后基于流程模板知道涉及哪些服務(wù)。
- 找到流程模板中維護(hù)的Xpath檢索項(xiàng)
- 基于Xpath檢索項(xiàng)找的信息,拼裝Solr查詢關(guān)鍵字,然后進(jìn)行Solr查找到對(duì)應(yīng)服務(wù)日志記錄。
- 將服務(wù)日志記錄提取出來對(duì)應(yīng)到流程實(shí)例具體的活動(dòng)節(jié)點(diǎn)上面。
- 完成流程實(shí)例圖的顯示。
當(dāng)我們點(diǎn)擊線條的時(shí)候可以查看到詳細(xì)的每筆接口服務(wù)調(diào)用日志信息。具體參考圖如下:
圖片
以上即是一個(gè)完整的基于Solr和ESB總線結(jié)合來實(shí)現(xiàn)端到端流程監(jiān)控的一個(gè)技術(shù)實(shí)現(xiàn)思路。該功能已經(jīng)在我們自研的ESB服務(wù)總線和IPaaS管控治理平臺(tái)得到實(shí)現(xiàn),并得到很好的展現(xiàn)效果。