微服務:SpringCloud 分佈式鏈路追蹤sleuth、zipkin

一、微服務架構下的問題

在大型系統的微服務化構建中,一個系統會被拆分成許多模塊。這些模塊負責不同的功能,組合成系統,最終可以提供豐富的功能。在這種架構中,一次請求往往需要涉及到多個服務。互聯網應用構建在不同的軟件模塊集上,這些軟件模塊,有可能是由不同的團隊開發、可能使用不同的編程語言來實現、有可能布在了幾千臺服務器,橫跨多個不同的數據中心,也就意味着這種架構形式也會存在一些問題:
  • 如何快速發現問題?
  • 如何判斷故障影響範圍?
  • 如何梳理服務依賴以及依賴的合理性?
  • 如何分析鏈路性能問題以及實時容量規劃?
分佈式鏈路追蹤(Distributed Tracing),就是將一次分佈式請求還原成調用鏈路,進行日誌記錄,性能監控並將 一次分佈式請求的調用情況集中展示。比如各個服務節點上的耗時、請求具體到達哪臺機器上、每個服務節點的請求狀態等等。
 
目前業界比較流行的鏈路追蹤系統如:TwitterZipkin,阿里的鷹眼,美團的Mtrace,大衆點評的cat等,大部分都是基於google發表的DapperDapper闡述了分佈式系統,特別是微服務架構中鏈路追蹤的概念、數據表示、埋點、傳遞、收集、存儲與展示等技術細節。
 

二、Sleuth

Spring Cloud Sleuth 主要功能就是在分佈式系統中提供追蹤解決方案,並且兼容支持了 zipkin,你只需要在pom文件中引入相應的依賴即可。
 
Spring Cloud Sleuth採用的是Google的開源項目Dapper的專業術語。
 
  • Span:基本工作單元,例如,在一個新建的span中發送一個RPC等同於發送一個迴應請求給RPC,span通過一個64ID唯一標識,trace以另一個64ID表示,span還有其他數據信息,比如摘要、時間戳事件、關鍵值註釋(tags)spanID、以及進度ID(通常是IP地址)span在不斷的啓動和停止,同時記錄了時間信息,當你創建了一個span,你必須在未來的某個時刻停止它。
  •  
    Trace:一系列spans組成的一個樹狀結構,例如,如果你正在跑一個分佈式大數據工程,你可能需要創建一個trace
  •  
    Annotation:用來及時記錄一個事件的存在,一些核心annotations用來定義一個請求的開始和結束。
    •  
      cs - Client Sent -客戶端發起一個請求,這個annotion描述了這個span的開始
    •  
      sr - Server Received -服務端獲得請求並準備開始處理它,如果將其sr減去cs時間戳便可得到網絡延遲
    •  
      ss - Server Sent -註解表明請求處理的完成(當請求返回客戶端),如果ss減去sr時間戳便可得到服務端需要的處理請求時間
    •  
      cr - Client Received -表明span的結束,客戶端成功接收到服務端的回覆,如果cr減去cs時間戳便可得到客戶端從服務端獲取回覆的所有所需時間
 
上面看不懂?沒關係!!!都是本人copy的一些專業術語
 

簡單的來說:這個分佈式鏈路追蹤就是一個查找錯誤、分析節點性能的東西。至於span和trace我們看下面一張小圖。

trace:整個鏈路調用,代表整個調用。span:每個最小工作單元,一次遠程服務調用。

這樣我們來通過trace和span就能夠實現鏈路追蹤了!!!

1、項目中整合sleuth

放入網關微服務、service-order微服務、service-product微服務中依賴:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>

分別加入日誌配置:

logging:
  level:
    root: info
    org.springframework.web.servlet.DispatcherServlet: DEBUG
    org.springframework.cloud.sleuth: DEBUG

重啓項目,看着這玩意。成功!!!

網關:traceID:0b48fa87c54c387a,span:0b48fa87c54c387a

service-order微服務,traceID:0b48fa87c54c387a,span:207b97ce89948d13

service-product微服務,traceID:0b48fa87c54c387a,span:d1b79f584d414475

從而驗證了我們上面那個小圖,一次遠程調用traceid是相同的,但是span是不同的。

老鐵們如果,這些信息存儲日誌中,就讓你們這麼看日誌,是不是很難受,所以引入下面的zipkin

三、zipkin

Zipkin Twitter 的一個開源項目,它基於 Google Dapper 實現,它致力於收集服務的定時數據,以解決微服務架構中的延遲問題,包括數據的收集、存儲、查找和展現。 我們可以使用它來收集各個服務器上請求鏈路的跟蹤數據,並通過它提供的 REST API 接口來輔助我們查詢跟蹤數據以實現對分佈式系統的監控程序,從而及時地發現系統中出現的延遲升高問題並找出系統性能瓶頸的根源。除了面向開發的 API 接口之外,它也提供了方便的 UI 組件來幫助我們直觀的搜索跟蹤信息和分析請求鏈路明細,比如:可以查詢某段時間內各用戶請求的處理時間等。 Zipkin 提供了可插拔數據存儲方式:In Memory、MySqlCassandra 以及 Elasticsearch
上圖展示了 Zipkin 的基礎架構,它主要由 4 個核心組件構成:
  • Collector:收集器組件,它主要用於處理從外部系統發送過來的跟蹤信息,將這些信息轉換爲Zipkin 內部處理的 Span 格式,以支持後續的存儲、分析、展示等功能。
  • Storage:存儲組件,它主要對處理收集器接收到的跟蹤信息,默認會將這些信息存儲在內存中,我們也可以修改此存儲策略,通過使用其他存儲組件將跟蹤信息存儲到數據庫中。
  •  RESTful APIAPI 組件,它主要用來提供外部訪問接口。比如給客戶端展示跟蹤信息,或是外接系統訪問以實現監控等。
  • Web UIUI 組件,基於 API 組件實現的上層應用。通過 UI 組件用戶可以方便而有直觀地查詢和分析跟蹤信息。
Zipkin 分爲兩端,一個是 Zipkin 服務端,一個是 Zipkin 客戶端,客戶端也就是微服務的應用。
客戶端會配置服務端的 URL 地址,一旦發生服務間的調用的時候,會被配置在微服務裏面的 Sleuth
監聽器監聽,並生成相應的 Trace Span 信息發送給服務端。
發送的方式主要有兩種,一種是 HTTP 報文的方式,還有一種是消息總線的方式如 RabbitMQ
 
不論哪種方式,我們都需要:
  • 一個 Eureka 服務註冊中心,這裏我們就用之前的 eureka 項目來當註冊中心。
  • 一個 Zipkin 服務端。
  •  

    多個微服務,這些微服務中配置Zipkin 客戶端。

1、Zipkin Server的部署和配置

1 Zipkin Server下載

spring boot 2.0開始,官方就不再支持使用自建Zipkin Server的方式進行服務鏈路追蹤,而是直接提供了編譯好的 jar 包來給我們使用。可以從官方網站下載先下載Zipkinweb UI,我們這裏下載的是zipkin-server-2.12.9-exec.jar。
 
2) 啓動
 
在命令行輸入 java -jar zipkin-server-2.12.9-exec.jar 啓動 Zipkin Server
 
  • 默認Zipkin Server的請求端口爲 9411
  • Zipkin Server的啓動參數可以通過官方提供的yml配置文件查找
  • 在瀏覽器輸入 http://127.0.0.1:9411即可進入到Zipkin Server的管理後臺
 

2、三個項目添加zipkin依賴

 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
        </dependency>

添加配置

spring:
  zipkin:
    base-url: http://127.0.0.1:9411
    sender:
      type: web # 數據的傳輸方式、以http方式傳遞到server
  sleuth:
    sampler:
      probability: 1 # 採集數據的比例

重啓一下項目:

就可以看到了。
 
不妥的問題:
 
(1)鏈路數據沒辦法持久化(保存),存儲在內存中
(2)http請求的方式,如果發生網絡波動,對我們的業務會造成影響。
 
解決:

3、zipkin數據保存到mysql中(解決第一個問題)

數據庫sql(在我們的項目源碼會給大家提供)
啓動項目的時候添加參數:
java -jar zipkin-server-2.12.9-exec.jar --STORAGE_TYPE=mysql --MYSQL_HOST=127.0.0.1 --MYSQL_TCP_PORT=3306 --MYSQL_DB=zipkin --MYSQL_USER=root --MYSQL_PASS=111111

然後就可以持久化到數據庫裏了。

4、連接消息中間件(解決第二個問題)

自己去安裝一下rabbitmq(偷偷的告訴你,用docker安裝賊快!!!)

java -jar zipkin-server-2.12.9-exec.jar --STORAGE_TYPE=mysql --MYSQL_HOST=127.0.0.1 --MYSQL_TCP_PORT=3306 --MYSQL_DB=zipkin --MYSQL_USER=root --MYSQL_PASS=111111 -RABBIT_ADDRESSES=127.0.0.1:5672

修改對應的配置:

  zipkin:
#    base-url: http://127.0.0.1:9411
    sender:
      type: rabbit
  #      type: web # 數據的傳輸方式、以http方式傳遞到server
  sleuth:
    sampler:
      probability: 1 # 採集數據的比例
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: user
    password: password
    listener:
      direct:
        retry:
          enabled: true
      simple:
        retry:
          enabled: true

 

證明了我們的配置正確。

源碼:[email protected]:Zesystem/springclouddedemowangguan.git

 

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