1、基本概念和整合
1.1、為什么用
微服務架構是一個分布式架構,它按業務劃分服務單元,一個分布式系統往往有很多個服務單元。由于服務單元數量眾多,業務的復雜性,如果出現了錯誤和異常,很難去定位 。主要體現在,一個請求可能需要調用很多個服務 ,而內部服務的調用復雜性,決定了問題難以定位。所以微服務架構中,必須實現分布式鏈路追蹤,去跟進一個請求到底有哪些服務參與,參與的順序又是怎樣的,從而達到每個請求的步驟清晰可見,出了問題,很快定位 。
鏈路追蹤組件有 Google 的 Dapper , Twitter 的 Zipkin ,以及阿里的 Eagleeye (鷹眼)等,它們都是非常優秀的鏈路追蹤開源組件。
1.2、基本術語
Span(跨度):基本工作單元,發送一個遠程調度任務 就會產生一個 Span,Span 是一個 64 位 ID 唯一標識的,Trace 是用另一個 64 位 ID 唯一標識的,Span 還有其他數據信息,比如摘要、時間戳事件、Span 的 ID、以及進度 ID。
Trace(跟蹤):一系列 Span 組成的一個樹狀結構。請求一個微服務系統的 API 接口,這個 API 接口,需要調用多個微服務,調用每個微服務都會產生一個新的 Span,所有由這個請求產生的 Span 組成了這個 Trace。
Annotation(標注):用來及時記錄一個事件的,一些核心注解用來定義一個請求的開始和結束 。這些注解包括以下:
cs - Client Sent -客戶端發送一個請求,這個注解描述了這個 Span 的開始
sr - Server Received -服務端獲得請求并準備開始處理它,如果將其 sr 減去 cs 時間戳便可得到網絡傳輸的時間。
ss - Server Sent (服務端發送響應)–該注解表明請求處理的完成(當請求返回客戶端),如果 ss 的時間戳減去 sr 時間戳,就可以得到服務器請求的時間。
cr - Client Received (客戶端接收響應)-此時 Span 的結束,如果 cr 的時間戳減去cs 時間戳便可以得到整個請求所消耗的時間。
官方文檔:GitHub - spring-cloud/spring-cloud-sleuth at 2.2.x
如果服務調用順序如下
那么用以上概念完整的表示出來如下:
Span 之間的父子關系如下:
2、整合 Sleuth
1、gulimall-common導入依賴
<!--鏈路追蹤 sleuth--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-sleuth</artifactId></dependency>
2 、每個微服務配置:打開 debug 日志
logging:level:org.springframework.cloud.openfeign: debugorg.springframework.cloud.sleuth: debug
3、發起一次遠程調用,觀察控制臺
查看商品詳情:http://item.gulimall.com/10.html
DEBUG [gulimall-product,541450f08573fff5,541450f08573fff5,false]
gulimall-product:服務名
541450f08573fff5:是 TranceId,一條鏈路中,只有一個 TranceId
541450f08573fff5:是 spanId,鏈路中的基本工作單元 id
false:表示是否將數據輸出到其他服務,true 則會把信息輸出到其他可視化的服務上觀察
3、整合 zipkin 可視化觀察
通過 Sleuth 產生的調用鏈監控信息,可以得知微服務之間的調用鏈路,但監控信息只輸出到控制臺不方便查看。我們需要一個圖形化的工具-zipkin 。 Zipkin 是 Twitter 開源的分布式跟蹤系統,主要用來收集系統的時序數據,從而追蹤系統的調用問題。
zipkin 官網地址如下: OpenZipkin · A distributed tracing system
1、docker 安裝 zipkin 服務器
docker run --name zipkin-server -d --restart=always -p 9411:9411 openzipkin/zipkin
2、導入
<!--鏈路追蹤 zipkin--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-zipkin</artifactId></dependency>
zipkin 依賴也同時包含了 sleuth,可以省略 sleuth 的引用
3、添加 zipkin 相關配置
spring:application:name: gulimall-product zipkin:base-url: http://192.168.56.10:9411/ # zipkin 服務器的地址# 關閉服務發現,否則 Spring Cloud 會把 zipkin 的 url 當做服務名稱discoveryClientEnabled: falsesender:type: web # 設置使用 http 的方式傳輸數據sleuth:sampler:probability: 1 # 設置抽樣采集率為 100%,默認為 0.1,即 10%
發送遠程請求,測試 zipkin。
訪問:http://192.168.56.10:9411/
服務調用鏈追蹤信息統計
使用本地zipkin
Central Repository: io/zipkin/java/zipkin-server
java -jar zipkin-server-2.9.4-exec.jar
啟動成功:
訪問:http://127.0.0.1:9411/
spring:application:name: gulimall-product zipkin:base-url: http://127.0.0.1:9411/ # zipkin 服務器的地址# 關閉服務發現,否則 Spring Cloud 會把 zipkin 的 url 當做服務名稱discoveryClientEnabled: falsesender:type: web # 設置使用 http 的方式傳輸數據sleuth:sampler:probability: 1 # 設置抽樣采集率為 100%,默認為 0.1,即 10%
4、Zipkin 數據持久化
Zipkin 默認是將監控數據存儲在內存的,如果 Zipkin 掛掉或重啟的話,那么監控數據就會丟失。所以如果想要搭建生產可用的 Zipkin,就需要實現監控數據的持久化。而想要實現數據持久化,自然就是得將數據存儲至數據庫。好在 Zipkin 支持將數據存儲至:
內存(默認)
MySQL
Elasticsearch
Cassandra
Zipkin 數據持久化相關的官方文檔地址如下:
GitHub - openzipkin/zipkin: Zipkin is a distributed tracing system
Zipkin 支持的這幾種存儲方式中,內存顯然是不適用于生產的,這一點開始也說了。
而使用MySQL 的話,當數據量大時,查詢較為緩慢,也不建議使用。
Twitter 官方使用的是 Cassandra作為 Zipkin 的存儲數據庫,但國內大規模用 Cassandra 的公司較少,而且 Cassandra 相關文檔也不多。
綜上,故采用 Elasticsearch 是個比較好的選擇,關于使用 Elasticsearch 作為 Zipkin 的存儲數據庫的官方文檔如下:
elasticsearch-storage :
zipkin/zipkin-server at master · openzipkin/zipkin · GitHub
zipkin-storage/elasticsearch
zipkin/zipkin-storage/elasticsearch at master · openzipkin/zipkin · GitHub
通過 docker 的方式
docker run --env STORAGE_TYPE=elasticsearch --env ES_HOSTS=192.168.56.10:9200
openzipkin/zipkin-dependencies
使用 es 時 Zipkin Dependencies 支持的環境變量