分佈式調用鏈監控組件的實踐與比較(一)實踐

http://www.javashuo.com/article/p-ccsdblwd-ec.htmljavascript

引言:最近在調研與選型分佈式調用鏈監控組件。選了主要的三種APM組件進行了實踐與比較。原本打算一篇文章寫完的,篇幅太長,打算分兩篇。本文主要講下鏈路traceing的基本概念和幾種APM組件的實踐,實踐部分也沒給出特別詳細的步驟,由於本文重點不在具體的步驟。第二篇將會講下幾種APM選型的比較與性能測試。java

640?wx_fmt=png

1. 問題背景mysql

640?wx_fmt=png

微服務架構下,服務按照不一樣的維度進行拆分,一次請求請求每每須要涉及到多個服務。互聯網應用構建在不一樣的軟件模塊集上,這些軟件模塊,有多是由不一樣的團隊開發、可能使用不一樣的編程語言來實現、有可能布在了幾千臺服務器,橫跨多個不一樣的數據中心。所以,就須要一些能夠幫助理解系統行爲、用於分析性能問題的工具,以便發生故障的時候,可以快速定位和解決問題。git

分佈式調用鏈監控組件在這樣的環境下產生了。最出名的是谷歌公開的論文提到的Dapper。開發Dapper是爲了收集更多的複雜分佈式系統的行爲信息,而後呈現給Google的開發者們。這樣的分佈式系統有一個特殊的好處,由於那些大規模的低端服務器,做爲互聯網服務的載體,是一個特殊的經濟划算的平臺。想要在這個上下文中理解分佈式系統的行爲,就須要監控那些橫跨了不一樣的應用、不一樣的服務器之間的關聯動做。程序員

市面上的APM(Application Performance Management)理論模型大多都是借鑑(borrow)Google Dapper論文,本文重點關注如下幾種APM組件:github

  • Zipkin
    由Twitter公司開源,開放源代碼分佈式的跟蹤系統,用於收集服務的定時數據,以解決微服務架構中的延遲問題,包括數據的收集、存儲、查找和展示。web

  • Pinpoint
    Pinpoint是一款對Java編寫的大規模分佈式系統的APM工具,由韓國人開源的分佈式跟蹤組件。redis

  • Skywalking
    國產的優秀APM組件,是一個對JAVA分佈式應用程序集羣的業務運行狀況進行追蹤、告警和分析的系統。spring

     

 

其餘相似的組件還有美團點評的CAT,淘寶的鷹眼EgleEye。sql

如上所述,那麼咱們選擇鏈路監控組件有哪些要求呢?Dapper中也提到了,筆者總結以下:

  • 探針的性能消耗。
    APM組件服務的影響應該作到足夠小。在一些高度優化過的服務,即便一點點損耗也會很容易察覺到,並且有可能迫使在線服務的部署團隊不得不將跟蹤系統關停。

  • 代碼的侵入性
    對於應用的程序員來講,是不須要知道有跟蹤系統這回事的。若是一個跟蹤系統想生效,就必須須要依賴應用的開發者主動配合,那麼這個跟蹤系統也太脆弱了,每每因爲跟蹤系統在應用中植入代碼的bug或疏忽致使應用出問題,這樣纔是沒法知足對跟蹤系統「無所不在的部署」這個需求。

  • 可擴展性
    可以支持的組件越多固然越好。或者提供便捷的插件開發API,對於一些沒有監控到的組件,應用開發者也能夠自行擴展。

  • 數據的分析
    數據的分析要快 ,分析的維度儘量多。跟蹤系統能提供足夠快的信息反饋,就能夠對生產環境下的異常情況作出快速反應。分析的全面,可以避免二次開發。

640?wx_fmt=png

2. 基礎概念

640?wx_fmt=png

上面列出的幾種組件,其中Zipkin是嚴格按照Google Dapper論文實現的,下面介紹下其中涉及的基本概念。

  • Span
    基本工做單元,一次鏈路調用(能夠是RPC,DB等沒有特定的限制)建立一個span,經過一個64位ID標識它,uuid較爲方便,span中還有其餘的數據,例如描述信息,時間戳,key-value對的(Annotation)tag信息,parent-id等,其中parent-id能夠表示span調用鏈路來源。

  • Trace:相似於樹結構的Span集合,表示一條調用鏈路,存在惟一標識。好比你運行的分佈式大數據存儲一次Trace就由你的一次請求組成。

  • Annotation: 註解,用來記錄請求特定事件相關信息(例如時間),一般包含四個註解信息:
    (1) cs:Client Start,表示客戶端發起請求

    (2) sr:Server Receive,表示服務端收到請求

    (3) ss:Server Send,表示服務端完成處理,並將結果發送給客戶端

    (4) cr:Client Received,表示客戶端獲取到服務端返回信息

2.1

Trace

下面看一下,在系統中Trace是什麼樣子。

640?wx_fmt=png

 

每種顏色的note標註了一個span,一條鏈路經過TraceId惟一標識,Span標識發起的請求信息。樹節點是整個架構的基本單元,而每個節點又是對span的引用。節點之間的連線表示的span和它的父span直接的關係。雖然span在日誌文件中只是簡單的表明span的開始和結束時間,他們在整個樹形結構中倒是相對獨立的。

 

 

2.2

 Span

640?wx_fmt=png

上圖說明了span在一次大的跟蹤過程當中是什麼樣的。Dapper記錄了span名稱,以及每一個span的ID和父ID,以重建在一次追蹤過程當中不一樣span之間的關係。若是一個span沒有父ID被稱爲root span。全部span都掛在一個特定的跟蹤上,也共用一個跟蹤id。

2.3

 Annotation

自動的探針,不須要修改應用程序源代碼,對應用開發者近乎零浸入的成本對分佈式控制路徑進行跟蹤,幾乎徹底依賴於基於少許通用組件庫的改造。Dapper還容許應用程序開發人員在Dapper跟蹤的過程當中添加額外的信息,以監控更高級別的系統行爲,或幫助調試問題。

下面章節將會介紹下上述三種APM組件的使用與實踐。

640?wx_fmt=png

 zipkin

640?wx_fmt=png

zipkin主要涉及幾個組件:collector收集agent的數據,storage存儲,web UI圖形化界面,search查詢Storage中存儲的數據,提供簡單的JSON API獲取數據。

640?wx_fmt=png

 

咱們的項目基於微服務框架spring cloud構建微服務。spring cloud也提供了spring-cloud-sleuth來方便集成zipkin實現。因此筆者就在項目中試了下spring-cloud-sleuth-zipkin。

起了三個服務:
zipkin-server、zipkin-client-backend、zipkin-client。
其中server服務負責收集以及信息展現。client-backend調用client,產生調用鏈路信息。

3.1

zipkin-server實現

zipkin-server實現主要有兩點須要注意,其一是收集到數據的存儲,方式包括內存、數據庫、ES等;其二是通訊方式,包括http通訊和mq異步方式通訊,http通訊會對正常的訪問形成影響,因此仍是推薦基於mq異步方式通訊。

本文使用mysql做爲存儲,使用MQ通訊,MQ通訊基於Spring-cloud-Stream。本文重點不在zipkin-server的具體幾種實現方式,其餘方式,讀者能夠本身去官網查看。

(1)pom須要添加的引用以下:

  1.  
    <dependency>
  2.  
      <groupId>org.springframework.boot</groupId>
  3.  
      <artifactId>spring-boot-starter< /artifactId>
  4.  
    </dependency>
  5.  
     
  6.  
    <!--zipkin依賴-->
  7.  
       <dependency>
  8.  
      <groupId>org.springframework.cloud</groupId>
  9.  
      <artifactId>spring-cloud-sleuth-zipkin-stream</artifactId>
  10.  
    </dependency>  
  11.  
     
  12.  
    <dependency>
  13.  
      <groupId>org.springframework.cloud</groupId>
  14.  
      <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
  15.  
    </dependency>
  16.  
     
  17.  
    <dependency>
  18.  
      <groupId>io.zipkin.java</groupId>
  19.  
      <artifactId>zipkin-autoconfigure-ui</artifactId>
  20.  
      <scope>runtime</scope>
  21.  
    </dependency>
  22.  
     
  23.  
    <!--保存到數據庫須要以下依賴-->
  24.  
    <dependency>
  25.  
      <groupId>mysql</groupId>
  26.  
      <artifactId>mysql-connector-java</artifactId>
  27.  
    </dependency>
  28.  
     
  29.  
    <dependency>
  30.  
      <groupId>org.springframework.boot</groupId>
  31.  
      <artifactId>spring-boot-starter-jdbc</artifactId>

(2)啓動類:

 

  1.  
    // 使用Stream方式啓動ZipkinServer
  2.  
    @EnableZipkinStreamServer
  3.  
    @SpringBootApplication
  4.  
    public class ZipkinStreamServerApplication {
  5.  
    public static void main(String[] args) {
  6.  
       SpringApplication.run(ZipkinStreamServerApplication.class,args);
  7.  
    }
  8.  
    }

@EnableZipkinStreamServer註解引入了@EnableZipkinServer註解,同時還建立了一個rabbit-mq的SleuthSink消息隊列監聽器。

 

(3)配置文件

 

  1.  
    server:
  2.  
    port: 9411
  3.  
    spring:
  4.  
    datasource:
  5.  
     username: root
  6.  
     password: root123
  7.  
     schema[ 0]: classpath:/zipkin.sql
  8.  
    zipkin:
  9.  
     storage:
  10.  
       type: mysql
  11.  
    ---
  12.  
    spring:
  13.  
    application:
  14.  
    name: microservice-zipkin-stream-server
  15.  
     rabbitmq:
  16.  
     host: ${RABBIT_ADDR:localhost}
  17.  
     port: ${RABBIT_PORT:5672}
  18.  
     username: guest
  19.  
     password: guest
  20.  
    sleuth:
  21.  
    enabled: false
  22.  
    profiles: default
  23.  
    datasource:
  24.  
     url:  jdbc:mysql://localhost:3307/zipkin? autoReconnect=true&useSSL=false

zipkin.sql能夠去官網獲取,設置了zipkin-server的端口號爲9411。

3.2

zipkin-client

兩個zipkin-client的配置同樣,因此放在一塊兒。

(1)pom依賴

  1.  
    <dependency>
  2.  
          <groupId>org.springframework.cloud</groupId>
  3.  
         <artifactId>spring-cloud-sleuth-zipkin-stream< /artifactId>
  4.  
     </dependency>
  5.  
      <dependency>
  6.  
          <groupId>org.springframework.cloud</groupId>
  7.  
          <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
  8.  
      </dependency>
  9.  
     <dependency>
  10.  
          <groupId>org.springframework.cloud</groupId>
  11.  
         <artifactId>spring-cloud-starter-sleuth< /artifactId>
  12.  
     </dependency>

(2) 配置文件

 

  1.  
    spring:
  2.  
    rabbitmq:
  3.  
     host: 127.0.0.1
  4.  
     port : 5672
  5.  
     username: guest
  6.  
     password: guest

3.3

結果

 

服務之間的調用關係以下:

 

640?wx_fmt=jpeg

 

能夠看到客戶端的請求通過gateway,調用內網中的各個服務,部分還涉及到調用notice服務。從圖中能夠清楚的看出客戶端請求所通過的服務。
下面看下demo2-default服務實例中的http path:

 

640?wx_fmt=jpeg

 

上圖中demo2-default服務的幾個http path按照時長排序,顯示了trace調用時長和span數量。點進去能夠看到:

 

640?wx_fmt=jpeg

 

圖中列出了從父span開始,每個span的耗時。本次trace中,涉及到兩個服務demo1和demo2。demo2調用demo1,從597ms開始調用demo1,完成最終的請求總共耗時1265ms。

 

 

640?wx_fmt=png

 pinpoint

640?wx_fmt=png

對代碼零侵入,運用JavaAgent字節碼加強技術,只須要加啓動參數便可。
pinpoint的幾個組件部分和zipkin差很少,架構圖以下:

 

640?wx_fmt=png

 

Pinpoint-Collector收集各類性能數據、Pinpoint-Agent和本身運行的應用關聯起來的探針、Pinpoint-Web將收集到的數據顯示成WEB網頁形式、HBase Storage收集到的數據存到HBase中。

4.1

pinpoint安裝

主要涉及如下軟件的安裝:

  • jdk 1.8
    Java環境必須的,沒啥好解釋。

  • Hbase
    pinpoint收集來的測試數據,主要是存在Hbase數據庫的。因此它能夠收集大量的數據,能夠進行更加詳細的分析。Hbase安裝完成後,須要初始化Hbase的pinpoint庫,由pinpoint提供。Hbase內置了zookeeper。

  • pinpoint-collector
    collector收集agent的數據,將數據存到hbase集羣,對外暴露collector的tcp和udp的監聽端口9994,9995,9996。

  • pinpoint-web
    頁面展現,配置文件中設置環境變量HBASE_HOST、HBASE_PORT等。

  • pinpoint-agent

到官網release頁面下載pinpoint-agent-x-SNAPSHOT.tar.gz,配置pinpoint.config中相關collector的信息。

安裝確實還比較麻煩,本文篇幅太長了,具體步驟後面再單獨寫文章講解。

4.2

運行pinpoint-agent

筆者使用的是spring-boot項目,因此只須要在啓動jar包的命令中加入-javaagent參數,並指定pinpoint-bootstrap包的絕對路徑。實例代碼以下:

 

java -javaagent:/aoho/auth_compose/pinpoint-bootstrap-1.6.0.jar -Dpinpoint.agentId=aoho-consumer -Dpinpoint.applicationName=aoho-consumer -jar id_generator/snowflake-id-generate-1.0-SNAPSHOT.jar

起的id生成器服務比較簡單,沒有用到數據庫等存儲介質。服務註冊到consul上,本地客戶端請求了id-server獲取id。其調用鏈以下:

640?wx_fmt=jpeg

pinpoint提供的功能比較豐富,下圖是調用/api/id接口的詳細信息。

 

640?wx_fmt=jpeg

 

能夠看到,pinpoint記錄了客戶端的相應時間、IP地址等,調用樹在下面也有詳細列出,每一個方法的耗時等。

 

640?wx_fmt=jpeg

 

serverMap中還展現了服務器的堆、永久代、CPU等信息,很是強大。

 

 

640?wx_fmt=png

Skywalking

640?wx_fmt=png

Skywalking是國內開源的APM監控組件,官網OpenSkywalking,根據官網介紹,其着力於性能和實時性兩方面。
網上找到的Skywalking的架構圖。

 

640?wx_fmt=png

能夠看到Skywalking也是四部分組成,collector、agent、web、storage。支持集羣部署,集羣之間還引入了grpc通訊。存儲支持內置的h2和elasticsearch存儲。

 

 

5.1

安裝

具體安裝可見官網。

  • collector安裝
    此處筆者使用單機版的collector,在release頁面下載好壓縮包,解壓後,單機版的collector默認使用h2數據庫,因此配置文件能夠不須要修改,便可以運行bin/startup.sh

  •  

640?wx_fmt=jpeg

 

目錄結構如上,logs文件夾中,有啓動的日誌,能夠查看啓動狀況。

  • web
    解壓好skywalking-ui,設置server的config/collector_config.properties、log4j2以及監聽端口等相關信息,

  • agent
    拷貝skywalking-agent目錄到所需位置,探針包含整個目錄,設置/config/agent.config中的collector信息。

5.2

運行agent

Spring boot的項目,啓動和上面pinpoint agent啓動方式相同。增長JVM啓動參數,-javaagent:/path/to/skywalking-agent/skywalking-agent.jar

此次起了user服務,涉及到mysql、redis、consul等組件。能夠看到其調用鏈路圖以下:

640?wx_fmt=jpeg

當訪問/api/external/register-code/api/external/validate-code接口時,造成了上圖中的調用鏈。

 

640?wx_fmt=jpeg

 

上圖TraceId爲 2.59.15103021777910001的請求/api/external/register-code。此次trace中,每一個涉及的span的耗時都有在圖中統計。

 

640?wx_fmt=jpeg

 

上面這張圖,是對userService中的Entry Service List接口進行了統計,包括調用數、成功率等信息。(由於內置的h2,這邊在UI響應好久)

還有個對instance的統計,統計jvm的相關信息,API響應也很慢,可能與我用的存儲有關吧,就不截圖了。

640?wx_fmt=png

總結

640?wx_fmt=png

本文主要寫了鏈路監控組件的實踐。首先介紹了鏈路監控組件產生與應用的背景,以及選擇的要求;其次介紹了opentracing中涉及的基本概念;最後大篇幅介紹了三種APM組件的安裝與使用,並展現了每種APM的UI截圖。

zipkin-server-stream的源碼github: https://github.com/keets2012/Spring-Boot-Samples/oschina: https://gitee.com/keets/spring-boot-samples

相關文章
相關標籤/搜索