從0開始服務化-0-調用鏈-Zipkin

Zipkin

Zipkin 是一個分佈式跟蹤系統,用於收集、管理和查找跟蹤數據。它可以把分佈式鏈路調用的順序串起來,並計算鏈路中每個 RPC 調用的耗時,可以很直觀的看出在整個調用鏈路中延遲問題。 Zipkin 的設計基於 GoogleDapper 論文實現的。

ZipkinServer 提供了 UI 操作,可以非常方便地查看和搜索跟蹤數據,直觀的查看到鏈調用依賴關係。

該項目包括一個無依賴庫和一個 spring-boot 服務器。存儲支持包括內存, JDBC(mysql)CassandraElasticsearch

在沒有使用外部存儲時,則默認使用內存存儲數據,內存數據是有限且不可持久化的,所以建議使用外部存儲,因日誌數據通常很大,爲了搜索日誌的效率,所以建議使用 Elasticsearch

Zipkin 的基礎架構由 4 個核心組件構成:

  • Collector:收集器組件,處理從外部系統發過來的跟蹤信息,將這些信息轉換爲 Zipkin 內部處理的 Span 格式,以支持後續的存儲、分析、展示等功能。
  • Stroage:存儲組件,主要處理收集器收到的跟蹤信息,默認存儲在內存中,也可通過 ES 或 JDBC 來存儲。
  • Restful API:API 組件,提供外部訪問接口。
  • Web UI:UI組件,基於 API 組件實現的 Web 控制檯,用戶可以很方便直觀地查詢、搜索和分析跟蹤信息。

部署測試服務

使用 docker 部署本地 zipkinserver

docker run -d -p 9411:9411 \
--name zipkin \
docker.io/openzipkin/zipkin

20191211171340

訪問:http://localhost:9411/zipkin/

20191211171424

構建測試項目

  • Service A

    server:
        port: 8081
    
    spring:
        application:
            name: server-a
        sleuth:
            web:
            client:
                enabled: true
            sampler:
            probability: 1.0 # 採用比例,默認 0.1 全部採樣 1.0
        zipkin:
            base-url: http://localhost:9411/ # 指定了Zipkin服務器的地址
    
    @Slf4j
    @RestController
    public class ServiceAController {
    
        @Resource
        private RestTemplate restTemplate;
    
        @GetMapping(value = "/servicea")
        public String servicea() {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.info("This is service a!");
            return restTemplate.getForObject("http://localhost:8082/serviceb", String.class);
        }
    }
    
  • Service B

    server:
       port: 8082
    
    spring:
        application:
            name: server-b
        sleuth:
            web:
            client:
                enabled: true
            sampler:
            probability: 1.0 # 採用比例,默認 0.1 全部採樣 1.0
        zipkin:
            base-url: http://localhost:9411/ # 指定了Zipkin服務器的地址
    
    @Slf4j
    @RestController
    public class ServiceBController {
    
        @Autowired
        private RestTemplate restTemplate;
    
        @GetMapping(value = "/serviceb")
        public String serviceb() {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.info("This is service b!");
            return restTemplate.getForObject("http://localhost:8083/servicec", String.class);
        }
    }
    
  • Service C

    server:
        port: 8083
    
    spring:
        application:
            name: server-c
        sleuth:
            web:
            client:
                enabled: true
            sampler:
            probability: 1.0 # 採用比例,默認 0.1 全部採樣 1.0
        zipkin:
            base-url: http://localhost:9411/ # 指定了Zipkin服務器的地址
    
    @Slf4j
    @RestController
    public class ServiceCController {
    
        @Resource
        private RestTemplate restTemplate;
    
        @GetMapping(value = "/servicec")
        public String servicec() {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.info("This is service c!");
            return "hello,this is server c!";
        }
    }
    

測試服務調用鏈-Sleuth

Zipkin 的依賴中包含了 SleuthSleuth 功能:

  • SpanIDTraceID 添加到 Slf4JMDC 中,這樣可以在日誌聚合器中根據 SpanIDTraceID 提取日誌。
  • 提供對常見分佈式跟蹤數據模型的抽象:traces(跟蹤)spans(形成DAG(有向無環圖)),註釋, key-value 註釋。鬆散地基於 HTrace ,但兼容 Zipkin(Dapper)
  • Sleuth 常見的入口和出口點來自 Spring 應用(Servlet 過濾器、Rest TemplateScheduled Actions、消息通道、Zuul Filter、Feign Client`)。
  • 如果 spring-cloud-sleuth-zipkin 可用,Sleuth 將通過 HTTP 生成並收集與 Zipkin 兼容的跟蹤。默認情況下,將跟蹤數據發送到 localhost(端口:9411)上的 Zipkin 收集服務應用,可使用 spring.zipkin.baseUrl 修改服務器地址。

啓動3個服務,訪問:http://localhost:8081/servicea,可以看到3個服務的日誌輸出如下:

20191211173729

20191211173754

20191211173809

在輸出的日誌中,多了些內容,這些內容就是由 sleuth 爲服務調用提供的鏈路信息
可以看到內容組成:[appname,traceId,spanId,exportable],具體含義如下:

  • appname:服務的名稱,即 spring.application.name 的值。
  • traceId:整個請求鏈路的唯一ID。
  • spanId:基本的工作單元,一個 RPC 調用就是一個新的 span。啓動跟蹤的初始 span 稱爲 root span ,此 spanId 的值與 traceId 的值相同。見上面示例消費者服務日誌輸出。
  • exportable:是否將數據導入到 Zipkin 中,true 表示導入成功,false 表示導入失敗。

Zipkin Server

再次訪問:http://localhost:9411/zipkin/,點擊查詢,可以看到剛纔執行的服務調用鏈:

20191211174929

點擊可以看到具體的調用時間與鏈路:

20191211175049

點擊具體的服務,可以看到服務調用的詳情以及父級子級 trace

20191211175127

項目地址

zipkin-demo

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章