1. 程式人生 > >【Springboot】例項講解Springboot整合OpenTracing分散式鏈路追蹤系統(Jaeger和Zipkin)

【Springboot】例項講解Springboot整合OpenTracing分散式鏈路追蹤系統(Jaeger和Zipkin)

# 1 分散式追蹤系統 隨著大量公司把單體應用重構為微服務,對於運維人員的責任就更加重大了。架構更復雜、應用更多,要從中快速診斷出問題、找到效能瓶頸,並不是一件容易的事。因此,也隨著誕生了一系列面向`DevOps`的診斷與分析系統,主要是以下三個系統: - 集中式日誌系統(Logging) - 集中式度量系統(Metrics) - 分散式追蹤系統(Tracing) 三者相互交織重疊如下: ![loggin_metrics_tracing](https://img2020.cnblogs.com/other/946674/202004/946674-20200405181335625-467469877.jpg) 技術棧上的成熟框架有, Logging:Log4j、ELK等, Metrics:Prometheus、InfluxDB、Grafana等 Tracing:Jaeger和Zipkin等。 分散式追蹤系統在Google發表一篇文章[Dapper, a Large-Scale Distributed Systems Tracing Infrastructure](https://research.google.com/pubs/pub36356.html?spm=a2c4e.10696291.0.0.335419a4mTcu58)後快速發展。Tracing系統一般核心步驟有三個:程式碼埋點、資料儲存、查詢展示。 歷史洪流滾滾向前,大浪淘沙,現在比較流行的有`Jaeger`和`Zipkin`。 # 2 OpenTracing 由於`Tracing`的技術發展迅速,為了解決相容性問題,有了[OpenTracing](https://opentracing.io/)規範。它是一個輕量級的標準化層,連線應用、類庫和追蹤系統。 ![interface](https://img2020.cnblogs.com/other/946674/202004/946674-20200405181336774-1678233158.jpg) OpenTracing的優勢: (1)OpenTracing已經進入`CNCF`(雲原生計算基金會,口號是堅持和整合開源技術來編排容器作為微服務架構的一部分),正在為全球的分散式追蹤,提供統一的概念和資料標準。 (2)OpenTracing通過提供平臺無關、廠商無關的`API`,使得開發人員能夠方便新增和更換追蹤系統的實現。 ## 2.1 相關概念 `Trace`:貫穿一個分散式系統的事務追蹤描述,其實就是由許多個`Span`組成的有向無環圖。 `Span`:被命名的與記錄時間的呼叫操作,如一個Http GET請求;`Span`有巢狀關係,如果一個請求會呼叫其它服務,就會生成子`Span`。 `Tag`:一組由鍵值對構成的標籤集合,鍵值型別必須為字串。它可以帶上許多有用資訊,如請求方法、請求URL、返回狀態碼等。 `Log`:一組`Span`的日誌集合。 ## 2.2 OpenTracing的實現 `Jaeger`是`Uber`推出的一款開源分散式追蹤系統,相容`OpenTracing API`。架構如下: ![Jaeger Architecture](https://img2020.cnblogs.com/other/946674/202004/946674-20200405181340611-1315311683.jpg) `Zipkin`是由`Twitter`推出的開源的分散式追蹤系統,架構圖如下: ![Zipkin architecture](https://img2020.cnblogs.com/other/946674/202004/946674-20200405181347816-1718860451.jpg) # 3 實戰整合 本文以Springboot為Web專案,分別整合`Jaeger`和`Zipkin`。 ## 3.1 Springboot專案準備 專案中的`Controller`,提供了兩個Endpoint,`tracing`和`open`;在訪問`open`時,程式碼會呼叫`tracing`。 ```java @RestController public class TracingController { @Autowired private RestTemplate restTemplate; @Value("${server.port}") private int port; @RequestMapping("/tracing") public String tracing() throws InterruptedException { Thread.sleep(100); return "tracing"; } @RequestMapping("/open") public String open() throws InterruptedException { ResponseEntity