《打造立體化監(jiān)控體系與APM最佳實踐系列 –Zipkin部署與使用》要點:
本文介紹了打造立體化監(jiān)控體系與APM最佳實踐系列 –Zipkin部署與使用,希望對您有用。如果有疑問,可以聯(lián)系我們。
年來在云計算、大數(shù)據(jù)等快速發(fā)展的時代下,產(chǎn)生了很多新的業(yè)務場景,同時很多企業(yè)傳統(tǒng)業(yè)務開始向互聯(lián)網(wǎng)的轉(zhuǎn)移.隨著企業(yè)業(yè)務的發(fā)展,規(guī)模擴大,業(yè)務越來越多,所采用的組件也越來越多開始走向分布式化,如微服務、消息收發(fā)、分布式數(shù)據(jù)庫、分布式對象存儲、分布式緩存、跨域調(diào)用等,這些組件共同構(gòu)成了繁雜的分布式網(wǎng)絡,一個業(yè)務請求可能會涉及到幾個、幾十個服務的協(xié)同處理,如何動態(tài)展示服務的鏈路?如何分析服務鏈路的瓶頸并對其進行調(diào)優(yōu)?如何快速進行服務鏈路的故障發(fā)現(xiàn)?如何保障產(chǎn)品服務的用戶體驗?企業(yè)需要一個從代碼端的視角來監(jiān)控自己的應用進而確保自身的IT支撐系統(tǒng)得到高效的運行,同時需要一個強大的IT運維管理體系時刻監(jiān)督IT環(huán)境各組件的性能質(zhì)量,通過多維度實時分析異常并進行診斷以解決產(chǎn)品的問題.因此,應用性能管理(APM)將逐漸成為推廣中國IT技術(shù)進步與用戶體驗提升的標配.
當前大的互聯(lián)網(wǎng)公司都有自己的分布式跟蹤系統(tǒng),比如Google的Dapper,Twitter的zipkin,Naver的pinpoint,淘寶的鷹眼,新浪的Watchman,京東的Hydra等,本文主要介紹zipkin的設計、安裝部署,并以一個簡單的案例演示zipkin的使用方法.
zipkin是一款開源的分布式實時數(shù)據(jù)追蹤系統(tǒng)(Distributed Tracking System),基于?Google Dapper的論文設計而來,由 Twitter 公司開發(fā)貢獻.其主要功能是聚集來自各個異構(gòu)系統(tǒng)的實時監(jiān)控數(shù)據(jù).
通過分析調(diào)用鏈,可以將一次請求的邏輯軌跡完整清晰的展示出來,通過在開發(fā)中在業(yè)務日志中添加調(diào)用鏈ID,可以通過調(diào)用鏈結(jié)合業(yè)務日志快速定位錯誤信息.
在調(diào)用鏈的各個環(huán)節(jié)分別添加調(diào)用時延,可以分析系統(tǒng)的性能瓶頸,進行有針對性的優(yōu)化.
通過分析各個環(huán)節(jié)的平均時延,QPS等信息,可以找到系統(tǒng)的薄弱環(huán)節(jié),對一些模塊做調(diào)整,例如數(shù)據(jù)冗余、鏈路可用等.
如上圖所示,zipkin主要包括四個模塊
??Collector接收各service傳輸?shù)臄?shù)據(jù)
??Storage存儲收集過來的數(shù)據(jù),當前支持Cassandra,Redis,HBase,MySQL,PostgreSQL,?SQLite等,默認存儲在內(nèi)存中.
??API(Query)負責查詢Storage中存儲的數(shù)據(jù),提供簡單的JSON API獲取數(shù)據(jù),主要提供給web UI使用
??Web?提供簡單的web界面
各個異構(gòu)的服務向zipkin報告數(shù)據(jù)的架構(gòu)如下圖:
上圖中的S表示發(fā)送跟蹤數(shù)據(jù)的客戶端SDK或者Scribe客戶端(twitter內(nèi)部采用scirbe來采集跟蹤數(shù)據(jù)).
Zipkin 以 Trace 結(jié)構(gòu)表示對一次請求的追蹤,又把每個 Trace 拆分為若干個有依賴關(guān)系的 Span.在微服務架構(gòu)中,一次用戶請求可能會由后臺若干個服務負責處理,那么每個處理請求的服務就可以理解為一個 Span(可以包括 API 服務,緩存服務,數(shù)據(jù)庫服務以及報表服務等).當然這個服務也可能繼續(xù)請求其他的服務,因此 Span 是一個樹形結(jié)構(gòu),以體現(xiàn)服務之間的調(diào)用關(guān)系.
Zipkin的Span模型幾乎完全仿造了Dapper中Span模型的設計,我們知道,Span用來描述一次RPC調(diào)用,所以一個RPC調(diào)用只應該關(guān)聯(lián)一個spanId,Zipkin中的Span主要包含三個數(shù)據(jù)部分:
??基礎(chǔ)數(shù)據(jù),包括traceId、spanId、parentId、name、timestamp和duration,主要用于跟蹤樹中節(jié)點的關(guān)聯(lián)和界面展示.
u?traceId:全局跟蹤ID,用它來標記一次完整服務調(diào)用,所以和一次服務調(diào)用相關(guān)的span中的traceId都是相同的,Zipkin將具有相同traceId的span組裝成跟蹤樹來直觀的將調(diào)用鏈路圖展現(xiàn)在我們面前.
u?spanid:span的id,理論上來說,span的id只要做到一個traceId下唯一就可以.
u?parentId:父span的id,調(diào)用有層級關(guān)系,所以span作為調(diào)用節(jié)點的存儲結(jié)構(gòu),也有層級關(guān)系,跟蹤鏈是采用跟蹤樹的形式來展現(xiàn)的,樹的根節(jié)點就是調(diào)用的頂點,其中parentId為null的Span將成為跟蹤樹的根節(jié)點來展示,當然它也是調(diào)用鏈的起點.
u?name:span的名稱,主要用于在界面上展示,一般是接口方法名,name的作用是讓人知道它是哪里采集的span.
u?timestamp:span創(chuàng)建時的時間戳,用來記錄采集的時刻.
u?duration:持續(xù)時間,即span的創(chuàng)建到span完成最終的采集所經(jīng)歷的時間,除去span自己邏輯處理的時間,該時間段可以理解成對于該跟蹤埋點來說服務調(diào)用的總耗時,timestamp+duration將表示成調(diào)用的結(jié)束時間.
??Annotation,注解,用來記錄請求特定事件相關(guān)信息(例如時間),通常包含四個注解信息
cs – Client Start,表示客戶端發(fā)起請求
sr – Server Receive,表示服務端收到請求
ss – Server Send,表示服務端完成處理,并將結(jié)果發(fā)送給客戶端
cr – Client Received,表示客戶端獲取到服務端返回信息
??BinaryAnnotation,提供一些額外信息,一般以key-value對出現(xiàn).
如下圖是一個調(diào)用鏈路示例:
在本文后續(xù)章節(jié)中將會對該實例進行詳細介紹.
在上一節(jié)中我們知道對于一個APM來說,提供多種類型的客戶端SDK(instrument)是很重要的,支持的客戶端SDK越多,推廣起來也越方便,使用人群也會越多.
跟蹤信息是使用instrument庫進行收集并發(fā)送給zipkin,截止目前,zipkin官方支持的客戶端SDK如下:
除了官方庫之后,社區(qū)也提供了instrument支持,社區(qū)支持庫如下:
zipkin支持兩種方式部署,docker容器以及jar包運行,
docker容器方式運行命令如下:
jar包直接運行命令如下(要求java8及以上版本):
5.2 服務開發(fā)
本文中以java語言開發(fā)一個簡單demo來演示zipkin的使用,Brave 是用來裝備 Java 程序的類庫,提供了面向 Standard Servlet、Spring MVC、Http Client、JAX RS、Jersey、Resteasy 和 MySQL 等接口的裝備能力,可以通過編寫簡單的配置和代碼,讓基于這些框架構(gòu)建的應用可以向 Zipkin 報告數(shù)據(jù).同時 Brave 也提供了非常簡單且標準化的接口,在以上封裝無法滿足要求的時候可以方便擴展與定制.
服務調(diào)用關(guān)系如下:
新建名為service1、service2、service3、service4四個spring boot類型的項目,下面以service1項目來描述項目詳細配置,其他項目的配置類似,在此不一一詳述.
pom.xml新增如下依賴:
application.properties中增加如下配置:
配置文件中指定了本服務的服務名以及服務端口,zipkin服務的地址.
服務定義:
當請求該服務(請求/start時),服務會請求下級的localhost:9090/foo服務-對應service2服務.
UI 啟動后主界面如下:
啟動服務service1、service2、service3、service4,并通過瀏覽器請求服務service1.
zipkin頁面查看服務
服務調(diào)用鏈如下:
查看服務依賴關(guān)系:
完整的服務跟蹤鏈信息如下:
[
{
“traceId”: “122ecddc1769c0da”,
“id”: “122ecddc1769c0da”,
“name”: “get”,
“timestamp”: 1494383123630139,
“duration”: 2832405,
“annotations”: [
{
“timestamp”: 1494383123630139,
“value”: “sr”,
“endpoint”: {
“serviceName”: “service1”,
“ipv4”: “192.168.1.10”
}
},
{
“timestamp”: 1494383126462544,
“value”: “ss”,
“endpoint”: {
“serviceName”: “service1”,
“ipv4”: “192.168.1.10”
}
}
],
“binaryAnnotations”: [
{
“key”: “http.status_code”,
“value”: “200”,
“endpoint”: {
“serviceName”: “service1”,
“ipv4”: “192.168.1.10”
}
},
{
“key”: “http.url”,
“value”: “/start”,
“endpoint”: {
“serviceName”: “service1”,
“ipv4”: “192.168.1.10”
}
}
]
},
{
“traceId”: “122ecddc1769c0da”,
“id”: “d92eb6cbae9b4787”,
“name”: “get”,
“parentId”: “122ecddc1769c0da”,
“timestamp”: 1494383123974246,
“duration”: 2475470,
“annotations”: [
{
“timestamp”: 1494383123974246,
“value”: “cs”,
“endpoint”: {
“serviceName”: “service1”,
“ipv4”: “192.168.1.10”
}
},
{
“timestamp”: 1494383124351184,
“value”: “sr”,
“endpoint”: {
“serviceName”: “service2”,
“ipv4”: “192.168.1.10”
}
},
{
“timestamp”: 1494383126443649,
“value”: “ss”,
“endpoint”: {
“serviceName”: “service2”,
“ipv4”: “192.168.1.10”
}
},
{
“timestamp”: 1494383126449716,
“value”: “cr”,
“endpoint”: {
“serviceName”: “service1”,
“ipv4”: “192.168.1.10”
}
}
],
“binaryAnnotations”: [
{
“key”: “http.status_code”,
“value”: “200”,
“endpoint”: {
“serviceName”: “service2”,
“ipv4”: “192.168.1.10”
}
},
{
“key”: “http.url”,
“value”: “/foo”,
“endpoint”: {
“serviceName”: “service2”,
“ipv4”: “192.168.1.10”
}
},
{
“key”: “http.url”,
“value”: “http://localhost:9090/foo”,
“endpoint”: {
“serviceName”: “service1”,
“ipv4”: “192.168.1.10”
}
}
]
},
{
“traceId”: “122ecddc1769c0da”,
“id”: “eba2687430a3f56c”,
“name”: “get”,
“parentId”: “d92eb6cbae9b4787”,
“timestamp”: 1494383124477917,
“duration”: 558367,
“annotations”: [
{
“timestamp”: 1494383124477917,
“value”: “cs”,
“endpoint”: {
“serviceName”: “service2”,
“ipv4”: “192.168.1.10”
}
},
{
“timestamp”: 1494383124881960,
“value”: “sr”,
“endpoint”: {
“serviceName”: “service3”,
“ipv4”: “192.168.1.10”
}
},
{
“timestamp”: 1494383125033410,
“value”: “ss”,
“endpoint”: {
“serviceName”: “service3”,
“ipv4”: “192.168.1.10”
}
},
{
“timestamp”: 1494383125036284,
“value”: “cr”,
“endpoint”: {
“serviceName”: “service2”,
“ipv4”: “192.168.1.10”
}
}
],
“binaryAnnotations”: [
{
“key”: “http.status_code”,
“value”: “200”,
“endpoint”: {
“serviceName”: “service3”,
“ipv4”: “192.168.1.10”
}
},
{
“key”: “http.url”,
“value”: “http://localhost:9091/bar”,
“endpoint”: {
“serviceName”: “service2”,
“ipv4”: “192.168.1.10”
}
},
{
“key”: “http.url”,
“value”: “/bar”,
“endpoint”: {
“serviceName”: “service3”,
“ipv4”: “192.168.1.10”
}
}
]
},
{
“traceId”: “122ecddc1769c0da”,
“id”: “3b0df0a2f1ea18b2”,
“name”: “get”,
“parentId”: “d92eb6cbae9b4787”,
“timestamp”: 1494383125298903,
“duration”: 1117321,
“annotations”: [
{
“timestamp”: 1494383125298903,
“value”: “cs”,
“endpoint”: {
“serviceName”: “service2”,
“ipv4”: “192.168.1.10”
}
},
{
“timestamp”: 1494383125529695,
“value”: “sr”,
“endpoint”: {
“serviceName”: “service4”,
“ipv4”: “192.168.1.10”
}
},
{
“timestamp”: 1494383126416224,
“value”: “cr”,
“endpoint”: {
“serviceName”: “service2”,
“ipv4”: “192.168.1.10”
}
},
{
“timestamp”: 1494383126424903,
“value”: “ss”,
“endpoint”: {
“serviceName”: “service4”,
“ipv4”: “192.168.1.10”
}
}
],
“binaryAnnotations”: [
{
“key”: “http.status_code”,
“value”: “200”,
“endpoint”: {
“serviceName”: “service4”,
“ipv4”: “192.168.1.10”
}
},
{
“key”: “http.url”,
“value”: “http://localhost:9092/tar”,
“endpoint”: {
“serviceName”: “service2”,
“ipv4”: “192.168.1.10”
}
},
{
“key”: “http.url”,
“value”: “/tar”,
“endpoint”: {
“serviceName”: “service4”,
“ipv4”: “192.168.1.10”
}
}
]
}
]
目前市面上已知APM包括zipkin、pinpoint、appdash、cat、hydra、EagleEye等,其中cat、hydra、EagleEye分別為美團、京東以及阿里內(nèi)部使用的系統(tǒng),有些未開源或者開源后不再更新,pinpoint由韓國的naver開源,zipkin由Twitter開源,當前zipkin以及pinpoint社區(qū)均非常活躍,版本發(fā)布也比較頻繁,用戶較多,生態(tài)系統(tǒng)也較為完善.
相對pinpoint的部署來說,zipkin部署比較簡單-運行jar包即可,pinpoint主要通過Plugin來支持眾多的模塊,包括tomcat、okhttpclient等中間件,基本不用修改源碼和配置文件,對于運維人員來講最為方便,zipkin通過instrument libraries來支持眾多的中間件,并且有Twitter等大公司的支持,但是開發(fā)時需要對Spring、web.xml之類的配置文件做修改.
文章來自微信公眾號:云技術(shù)實踐
轉(zhuǎn)載請注明本頁網(wǎng)址:
http://www.snjht.com/jiaocheng/4130.html