1. 程式人生 > >SpringCloud與zipkin(鏈路跟蹤)

SpringCloud與zipkin(鏈路跟蹤)

一、下載、安裝zipkin

zipkin的github地址:https://github.com/openzipkin/zipkin

下載:zipkin-server-2.11.5-exec.jar

執行:java -jar zipkin-server-2.11.5-exec.jar

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

二、在服務提供方、與消費方的pom.xml檔案中新增依賴

<!--服務鏈路監控(包含sleuth、zipkin)-->
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>

三、配置application.yml檔案

spring:
  application:
    name: consumer-dept
  zipkin:
       base-url: http://localhost:9411 #zipkin地址
  sleuth:
    sampler:
      percentage: 1 #抽樣百分比(預設是0.1,即10%)-(只抽樣監控10的請求%)

四、消費方發起請求,呼叫服務提供方的查詢部門資訊的介面

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import com.f6car.springcloud.entities.Dept;

@RestController
public class DeptController_Consumer {

    private static final String REST_URL_PREFIX = "http://MICROSERVICECLOUD-DEPT";

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping(value = "/consumer/dept/get/{id}")
    public Dept get(@PathVariable("id") Long id) {
        return restTemplate.getForObject(REST_URL_PREFIX + "/dept/get/" + id, Dept.class);
    }
}

五、檢視zipkin

點選json按鈕,檢視詳情資訊:

[
  {
    "traceId": "aba1676129d21fce",
    "parentId": "aba1676129d21fce",
    "id": "8aed49b22ffbb25a",
    "kind": "CLIENT",
    "name": "http:/dept/get/1",
    "timestamp": 1537668515817000,
    "duration": 445000,
    "localEndpoint": {
      "serviceName": "consumer-dept",
      "ipv4": "192.168.0.105",
      "port": 80
    },
    "tags": {
      "http.host": "MICROSERVICECLOUD-DEPT",
      "http.method": "GET",
      "http.path": "/dept/get/1",
      "http.url": "http://MICROSERVICECLOUD-DEPT/dept/get/1",
      "spring.instance_id": "192.168.0.105:consumer-dept:80"
    }
  },
  {
    "traceId": "aba1676129d21fce",
    "id": "aba1676129d21fce",
    "kind": "SERVER",
    "name": "http:/consumer/dept/get/1",
    "timestamp": 1537668515785000,
    "duration": 547193,
    "localEndpoint": {
      "serviceName": "consumer-dept",
      "ipv4": "192.168.0.105",
      "port": 80
    },
    "tags": {
      "mvc.controller.class": "DeptController_Consumer",
      "mvc.controller.method": "get",
      "spring.instance_id": "192.168.0.105:consumer-dept:80"
    }
  },
  {
    "traceId": "aba1676129d21fce",
    "parentId": "aba1676129d21fce",
    "id": "8aed49b22ffbb25a",
    "kind": "SERVER",
    "name": "http:/dept/get/1",
    "timestamp": 1537668516243000,
    "duration": 2000,
    "localEndpoint": {
      "serviceName": "microservicecloud-dept",
      "ipv4": "192.168.0.105",
      "port": 8001
    },
    "tags": {
      "mvc.controller.class": "DeptController",
      "mvc.controller.method": "get",
      "spring.instance_id": "192.168.0.105:microservicecloud-dept:8001"
    },
    "shared": true
  }
]

traceId:標記一次請求的跟蹤,相關的Spans都有相同的traceId;
id:span id;
name:span的名稱,一般是介面方法的名稱;
parentId:可選的id,當前Span的父Span id,通過parentId來保證Span之間的依賴關係,如果沒有parentId,表示當前Span為根Span;
timestamp:Span建立時的時間戳,使用的單位是微秒(而不是毫秒),所有時間戳都有錯誤,包括主機之間的時鐘偏差以及時間服務重新設定時鐘的可能性,
出於這個原因,Span應儘可能記錄其duration;
duration:持續時間使用的單位是微秒(而不是毫秒);
annotations:註釋用於及時記錄事件;有一組核心註釋用於定義RPC請求的開始和結束;

cs:Client Send,客戶端發起請求;
sr:Server Receive,伺服器接受請求,開始處理;
ss:Server Send,伺服器完成處理,給客戶端應答;
cr:Client Receive,客戶端接受應答從伺服器;

binaryAnnotations:二進位制註釋,旨在提供有關RPC的額外資訊。

六、補充

        一般的,一個分散式服務跟蹤系統,主要有三部分:資料收集、資料儲存和資料展示。根據系統大小不同,每一部分的結構又有一定變化。譬如,對於大規模分散式系統,資料儲存可分為實時資料和全量資料兩部分,實時資料用於故障排查(troubleshooting),全量資料用於系統優化;資料收集除了支援平臺無關和開發語言無關係統的資料收集,還包括非同步資料收集(需要跟蹤佇列中的訊息,保證呼叫的連貫性),以及確保更小的侵入性;資料展示又涉及到資料探勘和分析。雖然每一部分都可能變得很複雜,但基本原理都類似。         
       服務追蹤的追蹤單元是從客戶發起請求(request)抵達被追蹤系統的邊界開始,到被追蹤系統向客戶返回響應(response)為止的過程,稱為一個“trace”。每個 trace 中會呼叫若干個服務,為了記錄呼叫了哪些服務,以及每次呼叫的消耗時間等資訊,在每次呼叫服務時,埋入一個呼叫記錄,稱為一個“span”。這樣,若干個有序的 span 就組成了一個 trace。在系統向外界提供服務的過程中,會不斷地有請求和響應發生,也就會不斷生成 trace,把這些帶有span 的 trace 記錄下來,就可以描繪出一幅系統的服務拓撲圖。附帶上 span 中的響應時間,以及請求成功與否等資訊,就可以在發生問題的時候,找到異常的服務;根據歷史資料,還可以從系統整體層面分析出哪裡效能差,定位效能優化的目標。 
      Spring Cloud Sleuth為服務之間呼叫提供鏈路追蹤。通過Sleuth可以很清楚的瞭解到一個服務請求經過了哪些服務,每個服務處理花費了多長。從而讓我們可以很方便的理清各微服務間的呼叫關係。此外Sleuth可以幫助我們: 耗時分析: 通過Sleuth可以很方便的瞭解到每個取樣請求的耗時,從而分析出哪些服務呼叫比較耗時; 視覺化錯誤: 對於程式未捕捉的異常,可以通過整合Zipkin服務介面上看到; 鏈路優化: 對於呼叫比較頻繁的服務,可以針對這些服務實施一些優化措施。 spring cloud sleuth可以結合zipkin,將資訊傳送到zipkin,利用zipkin的儲存來儲存資訊,利用zipkin ui來展示資料。

這是Spring Cloud Sleuth的概念圖:

Zipkin 是一個開放原始碼分散式的跟蹤系統,由Twitter公司開源,它致力於收集服務的定時資料,以解決微服務架構中的延遲問題,包括資料的收集、儲存、查詢和展現。 每個服務向zipkin報告計時資料,zipkin會根據呼叫關係通過Zipkin UI生成依賴關係圖,顯示了多少跟蹤請求通過每個服務,該系統讓開發者可通過一個 Web 前端輕鬆的收集和分析資料,例如使用者每次請求服務的處理時間等,可方便的監測系統中存在的瓶頸。 Zipkin提供了可插拔資料儲存方式:In-Memory、MySql、Cassandra以及Elasticsearch。

Zipkin是什麼
Zipkin分散式跟蹤系統;它可以幫助收集時間資料,解決在microservice架構下的延遲問題;它管理這些資料的收集和查詢;Zipkin的設計是基於谷歌的Google Dapper論文。
每個應用程式向Zipkin報告定時資料,Zipkin UI呈現了一個依賴圖表來展示多少跟蹤請求經過了每個應用程式;如果想解決延遲問題,可以過濾或者排序所有的跟蹤請求,並且可以檢視每個跟蹤請求佔總跟蹤時間的百分比。

為什麼使用Zipkin
隨著業務越來越複雜,系統也隨之進行各種拆分,特別是隨著微服務架構和容器技術的興起,看似簡單的一個應用,後臺可能有幾十個甚至幾百個服務在支撐;一個前端的請求可能需要多次的服務呼叫最後才能完成;當請求變慢或者不可用時,我們無法得知是哪個後臺服務引起的,這時就需要解決如何快速定位服務故障點,Zipkin分散式跟蹤系統就能很好的解決這樣的問題。