jaeger opentracing Distributed Tracing

Java 整合 Jaeger(分散式追蹤系統)實作

葉文華 Todd Yeh 2021/10/22 10:00:00
3024

1. Jaeger 介紹

Jaeger 是 CNCF 的項目之一,由 Uber 開放源始碼的一個分散式追蹤系統,並且相容於 OpenTracing API。可用於追蹤微服務架構,聚合來自各個異構系統的即時觀察數據,可以用於監控交易、服務依賴分析程,以及性能/延遲優化。

2. 為什麼要使用分散式追蹤系統?

使用分散式追蹤系統,可以將需要觀察、追蹤的應用、服務...等架構中節點,透過共通的標準,將資訊匯整到一起。當資訊由不同的節點蒐集起來後,即能夠在相同的介面或數據集進行監控及分析,由於資料已經被整理為同質的資訊,也能夠進行比較、效能評估、事務追蹤。

結合 Kafka 快取緩衝機制的架構

 

3. Jaeger 應用實作

3.1. Docker 安裝 Jaeger

使用 Docker 來執行 Jaeger,可以在本機快速建立環境供驗證使用。

$ docker run -d --name jaeger \
  -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \
  -p 5775:5775/udp \
  -p 6831:6831/udp \
  -p 6832:6832/udp \
  -p 5778:5778 \
  -p 16686:16686 \
  -p 14268:14268 \
  -p 14250:14250 \
  -p 9411:9411 \
  jaegertracing/all-in-one:1.24

相關 Port 所提供服務:

 

執行起來後,可由以下 url 瀏覽 Jaeger UI:

http://localhost:16686/

 

3.2. 透過 Jaeger Client 推送 trace 到 Jaeger

在 Java 應用中有以下三種方式可進行

 

這邊實作採用侵入性最低的 java-specialagent 方式,它利用 Java 提供的 javaagent (Oracle docs - instrument) 機制,掛載 agent lib (Maven 下載 binary jar) 來採集資訊,透過在執行 Java 應用時加上如下 vm argument,即可快速達成代理推送資訊的目的。詳細的 argument 可參考 GitHub)。

-javaagent:opentracing-specialagent-1.7.4.jar
-Dsa.exporter=jaeger
-DJAEGER_ENDPOINT="http://localhost:14268/api/traces"
-DJAEGER_SAMPLER_TYPE=const
-DJAEGER_SAMPLER_PARAM=1
-DJAEGER_SERVICE_NAME="bpmutils"
-DJAEGER_PROPAGATION=b3

 

3.3. 使用 Jaeger 觀察 trace 資訊

利用網址 http://localhost:16686/ 瀏覽 Jaeger,查詢 trace 紀錄。

其中資訊的組成如下:

  • Trace:貫穿一個分散式系統的事務追蹤描述。
  • Span:一個被命名的請求操作與時間紀錄,如:一個 Http GET 請求;Span 有嵌套關系,如果一個請求會調用其它服務,就會生成子 Span。
  • Tag:一組由 <key, value> 構成的標簽集合。它包含許多有用訊息,如:請求方法、請求 URL、返回狀態碼等。
  • Log:一組 Span 的日誌集合。

 

3.3.1. Trace 如下圖中的一筆資料 (bpmutils:completeTask,由 49 筆 Spans 組成)

3.3.2. Span 如下圖紅框中條列的各個 Service & Operation,每筆 Span 中可查看藍框中詳細 Tags、Logs 等資訊

到這裡為止,已經簡單完成了分散式追蹤系統的體驗。

 

4. 後記

4.1. 提供豐富的模組支援常用 Java 套件

利用 javaagent 機制提供的 java-specialagent,其提供相當豐富的模組 Integrations,如:Apache HttpClient、Java JDBC API、Java Servlet API、Spring xxx...等常用套件的 trace 模組。詳細可參考 GitHub)。

例如透過以下 vm argument 先關閉全部 integration,再指定啟用 servlet、jdbc 兩個模組。

-Dsa.integration.*.disable=true
-Dsa.integration.servlet.enable=true
-Dsa.integration.jdbc.enable=true

 

4.2. Jaeger Client 推送 trace 的小阻礙

測試過程中,以 javaagent 並未指定 integration 啟動數次服務,觀察發現除了 servlet 外,其餘 integration rule 似乎未立即生效,如下圖 Traces 泡泡圖所示,在紅箭頭所示時間點約半小時候後,到藍色箭頭時間點位置開始才有密集的 rule 生效並進行收集。

若採用前述指定 servlet、jdbc 模組方式,則一開始就推送 trace 資訊,而不會有未立即生效問題。

 

4.3. java-specialagent 支援動態掛載 (Dynamic Attach) 的機制

在 Java 應用啟動後,透過掛載指定應用 PID 的方式,動態連接 javaagent 到目標應用上,此方式讓追蹤資訊的收集更靈活。

  • jdk1.8
java -Xbootclasspath/a:$JAVA_HOME/lib/tools.jar -jar opentracing-specialagent-1.7.4.jar ${PID}
  • jdk9+
java -jar opentracing-specialagent-1.7.4.jar ${PID}

 

5. 參考

葉文華 Todd Yeh
葉文華 Todd Yeh
2021/11/11 15:57:06

補充4.3.動態掛載機制實測,使用jdk1.8測試如以下,即可將已經在運行的「BPMUtilsApplication」服務加進蒐集資訊的行列了:

❯ jps

44624

8615 Launcher

8617 BPMUtilsApplication

444 MacLauncher

8622 Jps

 ❯ java -Xbootclasspath/a:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/lib/tools.jar -Dsa.exporter=jaeger -Dwf.service=delivery -DJAEGER_SERVICE_NAME="bpmutils" -jar /Users/user/Downloads/opentracing-specialagent-1.7.4.jar 8617