如何經過Zipkin或SKYwalking實現鏈路追蹤

前言

微服務架構將原先業務鏈條中的各個環節(節點或過程),如用戶、產品、訂單、支付拆分實現成獨立的服務運行,必定程度上提升了系統的容錯能力,例如支付服務失敗時,用戶依然能夠經過產品及訂單服務,達到查看訂單和瀏覽產品的目的。隨着微服務應用開發框架(如springboot)和容器技術(如K8)愈來愈成熟,微服務的開發和運維趨於標準化。這些都是微服務的愈發流行的緣由。同時,隨着業務複雜度的提升,愈來愈多的微服務被開發和集成進來,服務管理的重要性不言而喻。本文以服務調用的鏈路管理爲題,淺談微服務治理中鏈路管理的主流技術如何實踐。java

鏈路管理,主要指記錄服務的調用鏈路,一般用來定位不合理的服務設計,如鏈路過長帶來的服務耗時問題、鏈路過長帶來的服務穩定性風險、循環依賴等。鏈路管理,須要考慮哪些方面的問題,如何實現?mysql

  1. 首先,須要知道有哪些服務以及他們的服務狀態(服務註冊和發現機制),這個目前能夠直接經過spring cloud的Eureka實現,固然也能夠經過dubbo+zookeeper實現;
  2. 有了服務清單以後,咱們須要在每一個服務調用的地方攔截並記錄,記錄調用堆棧,從發起服務到鏈尾。這一步本身實現起來有較多的工做,譬如統一服務調用規則、AOP攔截、調用鏈數據結構定義、調用信息採集發送及存儲等。
  3. 最後,是鏈路數據的採集、存儲、發送以及最終的圖形化展現。

有了這個思路以後,咱們再來看目前主流的鏈路解決方案,Twitter的Zipkin,以及Apache的在孵化項目SKYwalking。固然還有些比較熱的方案,如韓國的開源項目Pinpoint和美團的CAT。這些方案從實現技術上大體可分爲兩個派系,攔截派,字節碼加強派。攔截派作法經過代理類攔截請求,將鏈路信息發送給服務器,Zipkin和CAT都屬於這種類型,不過CAT須要代碼侵入,即代碼中增長埋點,而Zipkin直接經過SpringCloud的Sleuth無縫對接SpringBoot的微服務。字節碼加強技術,經過JVMTI接口提供的javaagent(區別於JDK動態代理和CGLIB代理),利用字節碼操做技術(ASM),在類加載並實例化以前對class進行轉換,以後運行中將信息採集併發送給代理服務器(探針),如sk*walking的Agent服務。關於兩種方式的比較,小結以下:web

類型 zipkin SKYwalking
基本原理 攔截請求,發送(HTTP,mq)數據至zipkin服務 java探針,字節碼加強
接入方式 基於linkerd或者sleuth方式,引入配置便可 avaagent字節碼
支持OpenTracing
顆粒度 接口級(類級別) 方法級
存儲 ES,mysql,Cassandra,內存 ES,H2,TIDB
agent到collector的協議 http,MQ http,gRPC

Zipkin實踐

Zipkin 分爲兩端,Zipkin 服務端和Zipkin 客戶端,客戶端也就是微服務的應用。客戶端配置服務端的 URL 地址,一旦發生服務間的調用的時候,會被配置在微服務裏面的 Sleuth 的監聽器監聽,並生成相應的 Trace 和 Span 信息發送給服務端。發送的方式主要有兩種,一種是 HTTP 報文的方式,另外一種是消息總線的方式如 RabbitMQ。spring

不論哪一種方式,咱們都須要:一個 Eureka 服務註冊中心,先看下Zipkin運行架構:
如何經過Zipkin或SKYwalking實現鏈路追蹤sql

左側應用服務,同時也是Zipkin-clinet,Eureka-client, 中間是依賴,包括Zipkin-server和Eureka-server,最右側是WebUI展現及開發接口。docker

Zipkin 的服務端,在使用 Spring Boot 2.x 版本後,官方就不推薦自行定製編譯了,反而是直接提供了編譯好的 jar 包來給咱們使用。
因此官方提供了一鍵腳本數據庫

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

若是用 Docker 的話,直接
docker run -d -p 9411:9411 openzipkin/zipkinapache

這裏使用docker環境測試,數據存儲選擇默認的內存方式。啓動zipkinserver後,直接訪問9411,看到管理頁面:
如何經過Zipkin或SKYwalking實現鏈路追蹤springboot

zipkinserver啓動後,啓動EurekaServer,先本地啓動一個,端口暫定爲7777.
如何經過Zipkin或SKYwalking實現鏈路追蹤bash

好了,如今依賴服務有了,接下來改造兩個現有的微服務(爲至少兩個有調用關係的服務配置),做爲zkclient。要作的事情很簡單,下面幾步:

  1. 配置EurekaClient

1)微服務增長zipkin依賴

compile "org.springframework.cloud:spring-cloud-starter-sleuth"
compile "org.springframework.cloud:spring-cloud-starter-zipkin"

2) 啓動類增長EurekaClient註解
@EnableDiscoveryClient

3)application配置文件增長Eureka配置

eureka.instance.hostname=localhost
eureka.client.serviceUrl.defaultZone = http://${eureka.instance.hostname}:7777/eureka/
eureka.instance.preferIpAddress= true
  1. 配置Zipkin

1)開啓sleuth client

spring.sleuth.web.client.enabled=true
spring.sleuth.sampler.percentage=1.0

sampler.percentage是採樣率,1表明選取所有樣本,由於是測試,因此直接設置成1,實際狀況多是個小數,0.3或者0.5,根據需求自行決定。

2)配置zipkinserver地址
spring.zipkin.base-url=http://192.168.72.101:9411/

  1. 調用服務查看結果

1) Eureka服務清單
如何經過Zipkin或SKYwalking實現鏈路追蹤

2) Zipkin服務鏈路
如何經過Zipkin或SKYwalking實現鏈路追蹤

如何經過Zipkin或SKYwalking實現鏈路追蹤

須要注意的是,因爲Sleuth trace filter僅針對Spring內置的Rest調用作攔截,跨服務的調用須要使用Spring官宣方式,如RestTemplate,直接使用apache的httpclient工具包調用,是沒法追蹤到完整鏈路。

下面從實現層面瞭解,Zipkin的工做機制。引入sleuth和zipkin依賴包以後,系統自動掃描全部包中的@configuration,TraceAutoConfiguration是sleuth包的配置入口,看看它的定義,spring.sleuth.enabled開啓的時候註解有效。

@Configuration
@ConditionalOnProperty(
    value = {"spring.sleuth.enabled"},
    matchIfMissing = true
)
@EnableConfigurationProperties({TraceKeys.class, SleuthProperties.class})
public class TraceAutoConfiguration {
...

同理,Zipkin的配置以下:

@Configuration
@EnableConfigurationProperties({ZipkinProperties.class, SamplerProperties.class})
@ConditionalOnProperty(value = "spring.zipkin.enabled", matchIfMissing = true)
@AutoConfigureBefore(TraceAutoConfiguration.class)
public class ZipkinAutoConfiguration {
...

TraceFilter做爲整個追蹤的切入口,針對全部的request進行過濾標記,並經過AsyncReporter進行異步發送報文。下圖框起來的部分,分別是接口地址和編碼協議(Thrift)
如何經過Zipkin或SKYwalking實現鏈路追蹤

SKYwalking實踐

Zipkin使用起來很簡單,可是由於是接口級的跟蹤,能看到的信息比較有限,另外頁面的展現形式也相對簡單,缺乏多角度或者多樣性,因此,咱們再試試SKYWalking。
skywalking的工做機制,須要三塊協同,一塊是skywalking server,負責接收、存儲並展現,因此server模塊包含一個展現web子模塊;第二塊是agent,負責代理微服務並收集須要的信息,轉發給server;第三塊即是微服務自己,須要在啓動時指定agent,以便生成代理類。工做原理圖大體以下:

如何經過Zipkin或SKYwalking實現鏈路追蹤

先看下效果圖,再記錄配置過程。
如何經過Zipkin或SKYwalking實現鏈路追蹤

選中其中一個服務,能夠查看調用關係及服務基礎狀態。
如何經過Zipkin或SKYwalking實現鏈路追蹤

拓撲圖還有個扁平展現效果(很適合ppt介紹有沒有)
如何經過Zipkin或SKYwalking實現鏈路追蹤

儀表盤看服務狀態:
如何經過Zipkin或SKYwalking實現鏈路追蹤

追蹤欄看調用明細:
如何經過Zipkin或SKYwalking實現鏈路追蹤

失敗調用還有錯誤日誌:
如何經過Zipkin或SKYwalking實現鏈路追蹤

告警欄速覽全局風險:
如何經過Zipkin或SKYwalking實現鏈路追蹤

吹完療效,看下怎麼配置,先看server。

下載最新的skywalking,選了6.4,一開選的6.1有bug,拓撲圖常常出不來。server的運行能夠運行在容器內,也能夠運行虛擬服務器譬如ECS上。server的配置主要是存儲相關,mysql和es任選一個,看數據量和操做便捷性,數據量可控的狀況下,簡單起見,直接用mysql,換掉innodb引擎便可。

  1. 配置文件applicaiton.yml中打開datasource選項。
    如何經過Zipkin或SKYwalking實現鏈路追蹤
  2. datasource-setting.properties中指向自建的數據庫。(只須要建庫和訪問帳號,表在啓動時會自動初始化,表不少。。。)

server的訪問端口分別是:11800和12800,分別是gRPC和rest端口,若是改了,須要經過修改後面config的訪問端口。這裏提示開防火牆端口。

Agent的一樣有兩種方式,一種是將agent打在鏡像中,微服務的鏡像基於這個鏡像;另外一種是直接copy到一個共享目錄,每一個微服務啓動參數增長指向。第二種方式在測試環境比較實用,生產環境基本上用鏡像更合適,由於微服務運行在容器中,訪問共享目錄不現實。
無論選擇哪一種方式,config的配置是關鍵。
如何經過Zipkin或SKYwalking實現鏈路追蹤

agentName須要和微服務參數指定的一致。後臺服務地址指向oapserver。

最後一步,微服務啓動參數增長agent指向:
-Dskywalking.agent.application_code=agent-test
這個agent-test就是agentname,須要和agent配置的name一致!

非容器方式的配置主要就這三步,完事就能夠看到效果了。固然,服務以前的調用,須要用spring提供的restTemplate,不要直接用apache的httpclient工具包,不然不會被採集。關於容器環境的部署,後面抽空再補記錄。

相關文章
相關標籤/搜索