天天看點

穩定性專題 | 通過鍊路追蹤快速發現和定位業務問題的實踐

導讀

『StabilityGuide』是阿裡多位阿裡技術工程師共同發起的穩定性領域的知識庫開源項目,涵蓋性能壓測、故障演練、JVM、應用容器、服務架構、流量排程、監控、診斷等多個技術領域,以更結構化的方式來打造穩定性領域的知識庫,歡迎您的加入。

✅ @GitHub :

https://github.com/StabilityMan/StabilityGuide ✅ @釘釘群:
穩定性專題 | 通過鍊路追蹤快速發現和定位業務問題的實踐

  • 正文開始 -

🧯

引言

在可觀察性領域,Metrics,Tracing 和 Logging 的介紹由來已久。三種之間的邊界越來越模糊。OpenTracing 中已經支援 LogEvent,OpenTelemetry 已經把 OpenMetric 和 OpenTracing 整合到一塊。今天我們要介紹的鍊路追蹤的業務分析功能,通過對鍊路資料進行聚合統計,可以檢視各種業務報表。

穩定性專題 | 通過鍊路追蹤快速發現和定位業務問題的實踐

為什麼需要業務分析關聯鍊路資料?

精細化分析,全鍊路資料,快速發現和定位問題。

在傳統的 APM 分析中,主要是關注各種接口的響應時間,對業務不夠貼切,這樣會帶來一些問題:

發現問題

同一個接口被很多業務方調用,某一個重要業務調用出了問題,由于這個業務占比不高,無法通過平均數或者 p90 分析出來。例如建立訂單中重要客戶,這些客戶訂單占比不高,但是重要性比較高,需要重點分析和監控。

排查定位問題

某些使用者回報下單或者付款出現問題,但是這種情況隻存在少量使用者,重制比較困難。如果把使用者的異常和鍊路關聯起來,分析異常使用者的鍊路資料,比如出入參數,使用者屬性等,可以發現一些線索。例如檢視使用者 ID 對應的失敗訂單,分析訂單上鍊路,發現失敗訂單的來源都是某個舊版的用戶端調用。

業務分析概述

在介紹業務分析功能之前,先簡單提兩個問題,大家發散思考下怎麼解決這兩個問題。

1、某個應用的對外接口流量突增,是不是由于某個使用者或者地域流量暴漲?

2、應用出現比較多空指針異常,這些異常對業務有多大的影響?

通用的監控系統主要是對作業系統,分布式調用,資料庫元件進行監控。如果對業務監控,那就需要開發同學對調用鍊埋點添加業務屬性(用 tag 來記錄各種業務屬性)。通過對 tag 标簽進行過濾和統計聚合,達到業務分析和監控的效果。

穩定性專題 | 通過鍊路追蹤快速發現和定位業務問題的實踐

業務分析的實作方式

業務分析是在鍊路上标注一些業務資料,以下我們用 Jaeger 和 Skywalking 為例子講解業務埋點。

Jaeger 中添加 Tag 資訊

以 Java 語言為例,

// 擷取業務中的使用者Id
String userId = ****;
Tracer tracer = GlobalTracer.get();
if (tracer != null && tracer.activeSpan() != null) {
  // 将 UserId以 Tag 的形式存放到鍊路中
  tracer.activeSpan().setTag("userId", userId);
}           

Skywalking 中添加 Tag 資訊,

不插入代碼的方式:

https://github.com/apache/skywalking/blob/master/docs/en/setup/service-agent/java-agent/Customize-enhance-trace.md
<class class_name="test.apache.skywalking.testcase.customize.service.TestService2">
     <method method="staticMethod(java.lang.String,int.class)" operation_name="/is_2_static_method" static="true">
          <tag key="tag_2_1">arg[0]</tag>
          <log key="log_1_1">arg[1]</log>
     </method>
</class>           

用 OpenTracing 插入代碼方式

// global tracer object
private static Tracer tracer = new SkywalkingTracer();
...
 if (tracer != null && tracer.activeSpan() != null) {
      tracer.activeSpan().setTag("userId", yourUserId);
  }           

Java 代碼方式:

ActiveSpan.tag("userId", yourUserId);           

Java 注解方式

@Tag(key = "userId", value = "arg[0]")
@Tag(key = "requestId", value = "arg[1]")
public someMethod(final String userId, final String requestId) {
    // ...
}           

對鍊路資料進行業務分析

Tag 資訊就好比給圖書打上編号分類資訊,讓我們可以在圖書館海量的圖書中找到我們需要圖書。通過 Tag 來進行分類、查找、統計,可以快速找到我們需要的資料。

業務标簽的過濾

可以通過篩選 Tag 進行過濾,尋找所需要的鍊路。如下圖,檢視手機端下單的請求的變化趨勢,詳情等。

穩定性專題 | 通過鍊路追蹤快速發現和定位業務問題的實踐

業務标簽的聚合

指定 Tag 進行聚合,分析 Tag 聚合的統計。如下圖檢視每個入口(PC 和 Mobile)的請求數,響應時間,異常查詢。可以識别是不同業務的對比情況。

穩定性專題 | 通過鍊路追蹤快速發現和定位業務問題的實踐

業務分析的一些使用場景案例

Tag 功能主要是業務開發同學用來進行業務監控的, 通過在鍊路上寫入 Tag,可以把業務和鍊路打通,進而很好的發現,定位,跟蹤問題。

我們接下來做一些業務場景舉例。

業務異常分析

生成訂單時,會調用優惠,庫存,物流,商品等系統接口。這些接口都有可能會傳回異常,有些異常有些比較重要,有些隻是用于展示。我們怎麼快速識别目前應用的異常嚴重程度呢?可以通過加 Tag 的方式來實作。我們對異常進行分 1~5 級,1 級表示非常嚴重。

那我們每次調用遠端接口完成後,對傳回的異常添加 Tag,例如調用優惠時傳回系統異常加 Tag: tracer.activeSpan().setTag("bizErr", “1-PromotionSysExcep”); ,調用庫存傳回庫存不足,可以添加tracer.activeSpan().setTag("bizErr", “5-InventoryNotEmpty”);

那麼通過 Tag bizErr 進行聚合,對數量進行排序下,如果 1-** 開頭的比較多,那表示目前系統比較嚴重,需要緊急處理。檢視這些異常鍊路的請求參數或者傳回值,我們可以快速定位問題。

穩定性專題 | 通過鍊路追蹤快速發現和定位業務問題的實踐

使用者分析

将 UserId 用 Tag 方式寫入到 Span 中,可以統計到沒有使用者的資料,例如通路量,響應時間。我們之前遇到一個問題,Web 的流量突然變大,響應比較慢。從監控來看流量比較大,但為什麼流量會比較大呢,通過 UserId 分組統計後,發現某個使用者的流量暴漲,導緻整個背景響應比較慢,對這個使用者進行限流後,web流量和相應時間恢複正常。

穩定性專題 | 通過鍊路追蹤快速發現和定位業務問題的實踐

業務大盤

中台系統中各個業務的建立訂單大盤。

在中台應用中,各個業務使用同一個交易系統,通過訂單中的一個業務類型字段來區分不同的業務。通過在鍊路上的标簽,可以檢視到不同業務線的下單成功和失敗曲線。比如大盤上可以展示天貓,聚劃算,盒馬生鮮等業務的訂單情況。一旦有異常就可以分析鍊路的明細資訊來查找原因。

和傳統的統計不同點

傳統的 ELK 方式,使用者通過插入代碼,将業務的屬性都打到日志裡面。通過資料聚合,可以生成各種 Metrics,添加告警等。這樣做監控是合适的,但是需要更深層次的挖掘問題的話,還需要和鍊路打通。将監控的内容上下遊的資訊都串起來,可以更友善的定位問題。

比如:更新庫存失敗,發現異常都是上遊某個業務的某台機器上,而這條機器是灰階機器,使用了非穩定版本的。

總結

業務排查的問題方式有很多種,調用鍊和業務資訊打通已經是一種行之有效的方法。通過在調用鍊寫入業務資訊,将會給調用鍊配上顯微鏡,快速發現隐藏在鍊路資料中的各種問題。而業務資料關聯調用鍊,也給業務排查插上翅膀,從鍊路的上下文資訊中快速找到線索。

本文作者:徐建偉,花名竹影,阿裡雲技術專家,多年系統架構,性能調優經驗, 目前主要從事鍊路跟蹤,應用監控相關工作。