【Springboot】例項講解Springboot整合OpenTracing分散式鏈路追蹤系統(Jaeger和Zipkin)
阿新 • • 發佈:2020-04-05
# 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