Spring Cloud Alibaba學習筆記(23) - 調用鏈監控工具Spring Cloud Sleuth + Zipkin

隨着業務發展,系統拆分致使系統調用鏈路愈發複雜一個前端請求可能最終須要調用不少次後端服務才能完成,當整個請求陷入性能瓶頸或不可用時,咱們是沒法得知該請求是由某個或某些後端服務引發的,這時就須要解決如何快讀定位服務故障點,以對症下藥。因而就有了分佈式系統調用跟蹤的誕生。
Spring Cloud Sleuth 也爲咱們提供了一套完整的解決方案。在本文中,咱們將詳細介紹如何使用 Spring Cloud Sleuth + Zipkin 來爲咱們的微服務架構增長分佈式服務跟蹤的能力。前端

Spring Cloud Sleuth

Spring Cloud Sleuth implements a distributed tracing solution for Spring Cloud, borrowing heavily from Dapper, Zipkin and HTrace. For most users Sleuth should be invisible, and all your interactions with external systems should be instrumented automatically. You can capture data simply in logs, or by sending it to a remote collector service.java

Spring Cloud Sleuth是Spring Cloud實施分佈式跟蹤解決方案,大量借用Dapper,Zipkin和HTrace。 對於大多數用戶來講,偵探應該是隱形的,而且全部與外部系統的交互都應該自動進行檢測。 您能夠簡單地在日誌中捕獲數據,也能夠將數據發送到遠程收集器服務。mysql

SpringCloudSleuth 借用了 Dapper 的術語:git

  • Span(跨度):Sleuth的基本工做單元,它用一個64位的id惟一標識。除Id外,span還包含其餘數據,例如描述、時間戳事件、鍵值對的註解(標籤)、span ID、span父ID等
  • trace(跟蹤):一組span組成的樹狀結構稱之爲trace
  • Annotation(標註):用於及時記錄事件的存在
    • CS(Client Sent客戶端發送):客戶端發送一個請求,該annotation描述了span的開始
    • SR(Server Received服務器端接收):服務器端獲取請求並準備處理它
    • SS(Server Sent服務器端發送):該annotation代表完成請求處理(當響應發回客戶端時)
    • CR(Client Received客戶端接收):span結束的標識,客戶端成功接收到服務器端的響應

Spring Cloud Sleuth 爲服務之間調用提供鏈路追蹤。經過 Sleuth 能夠很清楚的瞭解到一個服務請求通過了哪些服務,每一個服務處理花費了多長。從而讓咱們能夠很方便的理清各微服務間的調用關係。此外 Sleuth 能夠幫助咱們:github

  • 耗時分析:經過 Sleuth 能夠很方便的瞭解到每一個採樣請求的耗時,從而分析出哪些服務調用比較耗時;
  • 可視化錯誤:對於程序未捕捉的異常,能夠經過集成 Zipkin 服務界面上看到;
  • 鏈路優化:對於調用比較頻繁的服務,能夠針對這些服務實施一些優化措施。

Spring Cloud Sleuth 能夠結合 Zipkin,將信息發送到 Zipkin,利用 Zipkin 的存儲來存儲信息,利用 Zipkin UI 來展現數據。web

這是 Spring Cloud Sleuth 的概念圖:
spring

應用整合Sleuth

只須要在pom.xml的dependencies中添加以下依賴,就能夠爲應用整合sleuth:sql

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

整合完成以後,啓動項目,調用一個請求(我人爲的關閉了應用要調用的另外一個微服務,致使了請求失敗),這是看控制檯日誌:shell

2019-10-29 16:28:57.417  INFO [study01,,,] 5830 --- [-192.168.31.101] o.s.web.servlet.DispatcherServlet        : Completed initialization in 27 ms
2019-10-29 16:28:57.430  INFO [study01,,,] 5830 --- [-192.168.31.101] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2019-10-29 16:28:57.433  INFO [study01,,,] 5830 --- [-192.168.31.101] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2019-10-29 16:28:58.520 DEBUG [study01,42d9bd786504f775,42d9bd786504f775,false] 5530 --- [nio-8881-exec-1] c.e.s.feignClient.CommentFeignClient     : [CommentFeignClient#find] ---> GET http://study02/find HTTP/1.1
2019-10-29 16:28:58.520 DEBUG [study01,42d9bd786504f775,42d9bd786504f775,false] 5530 --- [nio-8881-exec-1] c.e.s.feignClient.CommentFeignClient     : [CommentFeignClient#find] ---> END HTTP (0-byte body)
2019-10-29 16:28:58.520 DEBUG [study01,42d9bd786504f775,42d9bd786504f775,false] 5530 --- [nio-8881-exec-1] c.s.i.w.c.f.TraceLoadBalancerFeignClient : Before send
2019-10-29 16:28:58.646  INFO [study01,42d9bd786504f775,42d9bd786504f775,false] 5530 --- [nio-8881-exec-1] c.netflix.config.ChainedDynamicProperty  : Flipping property: study02.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
2019-10-29 16:28:58.661  INFO [study01,42d9bd786504f775,42d9bd786504f775,false] 5530 --- [nio-8881-exec-1] c.netflix.loadbalancer.BaseLoadBalancer  : Client: study02 instantiated a LoadBalancer: DynamicServerListLoadBalancer:{NFLoadBalancer:name=study02,current list of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:null
2019-10-29 16:28:58.667  INFO [study01,42d9bd786504f775,42d9bd786504f775,false] 5530 --- [nio-8881-exec-1] c.n.l.DynamicServerListLoadBalancer      : Using serverListUpdater PollingServerListUpdater
2019-10-29 16:28:58.683  INFO [study01,42d9bd786504f775,42d9bd786504f775,false] 5530 --- [nio-8881-exec-1] c.n.l.DynamicServerListLoadBalancer      : DynamicServerListLoadBalancer for client study02 initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=study02,current list of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:com.alibaba.cloud.nacos.ribbon.NacosServerList@591b62cf
2019-10-29 16:28:58.707 DEBUG [study01,42d9bd786504f775,42d9bd786504f775,false] 5530 --- [nio-8881-exec-1] o.s.c.s.i.a.ContextRefreshedListener     : Context successfully refreshed
2019-10-29 16:28:58.755 DEBUG [study01,42d9bd786504f775,42d9bd786504f775,false] 5530 --- [nio-8881-exec-1] c.s.i.w.c.f.TraceLoadBalancerFeignClient : Exception thrown

能夠看見日誌的形式和以前不太同樣了,首先啓動日誌裏面多了箇中括號:[study01,,,];而當應用請求報異常的時候,中括號中有了這些數據:[study01,42d9bd786504f775,42d9bd786504f775,false]
study01是應用名稱,42d9bd786504f775是 trace ID,42d9bd786504f775是span ID,false表示是否是要把這條數據上傳給zipkin。這時,就能夠經過日誌分析應用哪裏出了問題、哪一個階段出了問題。後端

PS:能夠在應用中添加以下配置:

logging:
  level:
    org.springframework.cloud.sleuth: debug

這段配置的用處是讓sleuth打印更多的日誌,從而進一步幫助咱們分析錯誤【我上面粘出的日誌就是添加配置以後的結果】。

Zipkin

Zipkin 是 Twitter 的開源分佈式跟蹤系統,它基於 Google Dapper 實現,它致力於收集服務的時序數據,以解決微服務架構中的延遲問題,包括數據的收集、存儲、查找和展示。

搭建Zipkin Server

下載Zipkin Server

使用Zipkin官方的Shell

curl -sSL https://zipkin.io/quickstart.sh | bash -s

Maven中央倉庫

訪問以下地址下載:
https://search.maven.org/remote_content?g=io.zipkin.java&a=zipkin-server&v=LATEST&c=exec

啓動Zipkin Server

下載完成以後,在下載的jar所在目錄,執行java -jar *****.jar命令便可啓動Zipkin Server
訪問http://localhost:9411 便可看到Zipkin Server的首頁。

應用整合Zipkin

添加依賴:

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

PS:當使用了spring-cloud-starter-zipkin以後,前面添加spring-cloud-starter-sleuth就不須要了,由於前者包含了後者。

添加配置

spring:
  zipkin:
    base-url: http://localhost:9411/
  sleuth:
    sampler:
      # 抽樣率,默認是0.1(90%的數據會被丟棄)
      # 這邊爲了測試方便,將其設置爲1.0,即全部的數據都會上報給zipkin
      probability: 1.0

啓動項目,產生請求以後,打開zipkin控制檯,能夠剛剛請求的信息(按耗時降序排列):

點擊能夠查看請求的詳情:

這張圖中,Server Start表示的是Server ReceivedServer Finish表示的是Server Sent
由於客戶端發生在瀏覽器上,而瀏覽器並無整合zipkin,因此zipkin中沒有Client SentClient Received數據。

Zipkin數據持久化

前面搭建Zipkin是基於內存的,若是Zipkin發生重啓的話,數據就會丟失,這種方式是不適用於生產的,因此咱們須要實現數據持久化。
Zipkin給出三種數據持久化方法:

  • MySQL:存在性能問題,不建議使用
  • Elasticsearch
  • Cassandra

相關的官方文檔:https://github.com/openzipkin/zipkin#storage-component , 本文將介紹Elasticsearch實現Zipkin數據持久化

搭建Elasticsearch

咱們須要下載什麼版本的Elasticsearch呢,官方文檔給出了建議,5-7版本均可以使用(本文使用的是Elasticsearch6.8.2,由於Elasticsearch7開始後須要jdk11支持):

The Elasticsearch component uses Elasticsearch 5+ features, but is tested against Elasticsearch 6-7.x.

下載完成後,解壓縮軟件包,進入bin目錄,執行./elasticsearch便可啓動Elasticsearch:

訪問http://localhost:9200/,出現以下頁面,說明Elasticsearch啓動成功:

讓zipkin使用Elasticsearch存儲數據

zipkin提供了不少的環境變量,配置環境變量就能夠將數據存儲進Elasticsearch。

  • STORAGE_TYPE: 指定存儲類型,可選項爲:mysql, cassandra, elasticsearch
  • ES_HOSTS:Elasticsearch地址,多個使用,分隔,默認http://localhost:9200
  • ES_PIPELINE:指定span被索引以前的pipeline(Elasticsearch的概念)
  • ES_TIMEOUT:鏈接Elasticsearch的超時時間,單位是毫秒;默認10000(10秒)
  • ES_INDEX:zipkin所使用的索引前綴(zipkin會天天創建索引),默認zipkin
  • ES_DATE_SEPARATOR:zipkin創建索引的日期分隔符,默認是-
  • ES_INDEX_SHARDS:shard(Elasticsearch的概念)個數,默認5
  • ES_INDEX_REPLICAS:副本(Elasticsearch的概念)個數,默認1
  • ES_USERNAME/ES_PASSWORD:Elasticsearch帳號密碼
  • ES_HTTP_LOGGING:控制Elasticsearch Api的日誌級別,可選項爲BASIC、HEADERS、BODY

更多環境變量參照:https://github.com/openzipkin/zipkin/tree/master/zipkin-server#environment-variables

執行下面代碼從新啓動zipkin:

STORAGE_TYPE=elasticsearch ES_HOSTS=localhost:9200 java -jar zipkin-server-2.12.9-exec.jar

產生請求以後,訪問http://localhost:9411/zipkin/,能夠看見剛剛請求的數據:

停調zipkin,而後再次啓動,訪問http://localhost:9411/zipkin/,能夠看見數據依然存在:

說明此時,數據已經實現了持久化。

從官方文檔能夠看出,使用Elasticsearch進行zipkin數據持久化以後,Zipkin的依賴關係分析功能沒法使用了。

Note: This store requires a spark job to aggregate dependency links.
咱們須要整合zipkin-dependencies來實現依賴關係圖功能。zipkin-dependencies是zipkin的一個子項目,啓動很是的簡單。

下載:
curl -sSL https://zipkin.io/quickstart.sh | bash -s io.zipkin.dependencies:zipkin-dependencies:LATEST zipkin-dependencies.jar
啓動:
STORAGE_TYPE=elasticsearch ES_HOSTS=localhost:9200 java -jar zipkin-dependencies.jar

zipkin-dependencies使用Elasticsearch的環境變量

  • STORAGE_TYPE: 指定存儲類型,可選項爲:mysql, cassandra, elasticsearch
  • ES_HOSTS:Elasticsearch地址,多個使用,分隔,默認http://localhost:9200
  • ES_INDEX:zipkin所使用的索引前綴(zipkin會天天創建索引),默認zipkin
  • ES_DATE_SEPARATOR:zipkin創建索引的日期分隔符,默認是-
  • ES_NODES_WAN_ONLY:若是設爲true,則表示僅使用ES_HOSTS所設置的值,默認爲false。當Elasticsearch集羣運行在Docker中時,可將該環境變量設爲true。

這邊只須要把項目啓動,就能夠展現依賴關係圖了,這裏就再也不演示了。
注意:zipkin-dependencies啓動以後會自動中止,因此建議使用定時任務讓操做系統定時啓動zipkin-dependencies。

擴展:Zipkin Dependencies指定分析日期:

分析昨天的數據(OS/X下的命令) STORAGE_TYPE=elasticsearch java -jar zipkin-dependencies.jar 'date -uv-ld + %F' 分析昨天的數據(Linux下的命令) STORAGE_TYPE=elasticsearch java -jar zipkin-dependencies.jar 'date -u -d '1 day ago' + %F' 分析指定日期的數據 STORAGE_TYPE=elasticsearch java -jar zipkin-dependencies.jar 2019-10-29

相關文章
相關標籤/搜索