分布式服務(wù)跟蹤及Spring Cloud的實(shí)現(xiàn)

看了了一個(gè)關(guān)于分布式服務(wù)鏈路追蹤的文章荚孵,覺(jué)得寫(xiě)得不錯(cuò)爷辙,轉(zhuǎn)載記錄左权,原文鏈接:http://daixiaoyu.com/distributed-tracing.html
附上最近學(xué)習(xí)spring cloud做的demo:https://github.com/applenele/springcloudsample

在分布式服務(wù)架構(gòu)中拘领,需要對(duì)分布式服務(wù)進(jìn)行治理——在分布式服務(wù)協(xié)同向用戶提供服務(wù)時(shí)藕帜,每個(gè)請(qǐng)求都被哪些服務(wù)處理烫罩?在遇到問(wèn)題時(shí),在調(diào)用哪個(gè)服務(wù)上發(fā)生了問(wèn)題洽故?在分析性能時(shí)贝攒,調(diào)用各個(gè)服務(wù)都花了多長(zhǎng)時(shí)間?哪些調(diào)用可以并行執(zhí)行时甚?…… 為此隘弊,分布式服務(wù)平臺(tái)就需要提供這樣一種基礎(chǔ)服務(wù)——可以記錄每個(gè)請(qǐng)求的調(diào)用鏈;調(diào)用鏈上調(diào)用每個(gè)服務(wù)的時(shí)間撞秋;各個(gè)服務(wù)之間的拓?fù)潢P(guān)系…… 我們把這種行為稱為“分布式服務(wù)跟蹤”长捧。

背景

現(xiàn)今業(yè)界分布式服務(wù)跟蹤的理論基礎(chǔ)主要來(lái)自于 Google 的一篇論文《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》,使用最為廣泛的開(kāi)源實(shí)現(xiàn)是 Twitter 的 Zipkin吻贿,為了實(shí)現(xiàn)平臺(tái)無(wú)關(guān)串结、廠商無(wú)關(guān)的分布式服務(wù)跟蹤,CNCF 發(fā)布了布式服務(wù)跟蹤標(biāo)準(zhǔn) Open Tracing。國(guó)內(nèi)肌割,淘寶的“鷹眼”卧蜓、京東的“Hydra”、大眾點(diǎn)評(píng)的“CAT”把敞、新浪的“Watchman”弥奸、唯品會(huì)的“Microscope”、窩窩網(wǎng)的“Tracing”都是這樣的系統(tǒng)奋早。

image.png

原理

一般的盛霎,一個(gè)分布式服務(wù)跟蹤系統(tǒng),主要有三部分:數(shù)據(jù)收集耽装、數(shù)據(jù)存儲(chǔ)和數(shù)據(jù)展示愤炸。根據(jù)系統(tǒng)大小不同,每一部分的結(jié)構(gòu)又有一定變化掉奄。譬如规个,對(duì)于大規(guī)模分布式系統(tǒng),數(shù)據(jù)存儲(chǔ)可分為實(shí)時(shí)數(shù)據(jù)和全量數(shù)據(jù)兩部分姓建,實(shí)時(shí)數(shù)據(jù)用于故障排查(troubleshooting)诞仓,全量數(shù)據(jù)用于系統(tǒng)優(yōu)化;數(shù)據(jù)收集除了支持平臺(tái)無(wú)關(guān)和開(kāi)發(fā)語(yǔ)言無(wú)關(guān)系統(tǒng)的數(shù)據(jù)收集速兔,還包括異步數(shù)據(jù)收集(需要跟蹤隊(duì)列中的消息墅拭,保證調(diào)用的連貫性),以及確保更小的侵入性憨栽;數(shù)據(jù)展示又涉及到數(shù)據(jù)挖掘和分析帜矾。雖然每一部分都可能變得很復(fù)雜,但基本原理都類似。

image.png

服務(wù)追蹤的追蹤單元是從客戶發(fā)起請(qǐng)求(request)抵達(dá)被追蹤系統(tǒng)的邊界開(kāi)始波俄,到被追蹤系統(tǒng)向客戶返回響應(yīng)(response)為止的過(guò)程闹瞧,稱為一個(gè)“trace”。每個(gè) trace 中會(huì)調(diào)用若干個(gè)服務(wù)泪幌,為了記錄調(diào)用了哪些服務(wù),以及每次調(diào)用的消耗時(shí)間等信息,在每次調(diào)用服務(wù)時(shí)唧瘾,埋入一個(gè)調(diào)用記錄,稱為一個(gè)“span”别凤。這樣饰序,若干個(gè)有序的 span 就組成了一個(gè) trace。在系統(tǒng)向外界提供服務(wù)的過(guò)程中规哪,會(huì)不斷地有請(qǐng)求和響應(yīng)發(fā)生求豫,也就會(huì)不斷生成 trace,把這些帶有span 的 trace 記錄下來(lái),就可以描繪出一幅系統(tǒng)的服務(wù)拓?fù)鋱D蝠嘉。附帶上 span 中的響應(yīng)時(shí)間最疆,以及請(qǐng)求成功與否等信息,就可以在發(fā)生問(wèn)題的時(shí)候蚤告,找到異常的服務(wù)努酸;根據(jù)歷史數(shù)據(jù),還可以從系統(tǒng)整體層面分析出哪里性能差杜恰,定位性能優(yōu)化的目標(biāo)获诈。

image.png

實(shí)現(xiàn)

Spring Cloud 是基于 Java 的分布式服務(wù)平臺(tái),提供一系列的分布式服務(wù)所需的中間件心褐。其中舔涎,用于分布式服務(wù)跟蹤的模塊是 Spring Cloud Sleuth

Spring Cloud Sleuth 主要用于收集 Spring Boot 程序中的數(shù)據(jù)檬寂,即上文所說(shuō)的數(shù)據(jù)收集终抽。其包含的 spring-cloud-sleuth-zipkin 模塊可以把收集到的數(shù)據(jù)發(fā)送到 zipkin 服務(wù)器。Zipkin 本身具有數(shù)據(jù)存儲(chǔ)和展示的功能桶至,這樣昼伴,我們就可以在 Spring Boot 系統(tǒng)中埋入 Spring Cloud Sleuth 收集數(shù)據(jù),在后臺(tái)使用 Zipkin 服務(wù)作為數(shù)據(jù)存儲(chǔ)和展示的服務(wù)镣屹。

使用 Zipkin 作為后臺(tái)的另一個(gè)好處是圃郊,Zipkin 除了支持 Spring Cloud Sleuth 以外,還支持其他開(kāi)發(fā)語(yǔ)言和平臺(tái)的數(shù)據(jù)收集器女蜈。這使得在系統(tǒng)中讓不同種種語(yǔ)言開(kāi)發(fā)的服務(wù)可以共存持舆。

首先,我們要搭建一個(gè) Zipkin 的后臺(tái)服務(wù)伪窖,然后把我們已有的 Spring Boot 服務(wù)中埋入 Spring Cloud Sleuth逸寓,最后,將 Spring Cloud Sleuth 接入 Zipkin 服務(wù)覆山,一個(gè)非常簡(jiǎn)單的分布式服務(wù)跟蹤服務(wù)就搭建起來(lái)了竹伸。

搭建 Zipkin 最簡(jiǎn)單的辦法是直接使用 Zipkin 官方的 Docker 鏡像。Zipkin 的存儲(chǔ)引擎也是可以配置的簇宽,啟動(dòng) Zipkin 時(shí)勋篓,如果沒(méi)有配置 Zipkin 的存儲(chǔ)引擎,那么默認(rèn) Zipkin 把數(shù)據(jù)存在內(nèi)存中魏割。這里譬嚣,由于我們已經(jīng)有了一個(gè) MySQL 的高可用環(huán)境,所以配置 MySQL 為 Zipkin 的存儲(chǔ)引擎钞它。

# 下載鏡像
docker pull openzipkin/zipkin
# 運(yùn)行鏡像拜银,并指定存儲(chǔ)引擎
docker run -d -p 9411:9411 -e MYSQL_USER=root -e MYSQL_PASS=password -e MYSQL_HOST=192.168.0.8 -e STORAGE_TYPE=mysql openzipkin/zipkin

Zipkin 運(yùn)行起來(lái)后殊鞭,可以通過(guò)瀏覽器訪問(wèn) 9411 端口,確認(rèn) Zipkin 的運(yùn)行狀態(tài)盐股。

image.png

接下來(lái)需要改造已有的 Spring Boot 服務(wù)钱豁。

首先,在 pom.xml 中引入 Spring Cloud Sleuth疯汁。因?yàn)槭?zipkin 模塊牲尺,所以只引入 spring-cloud-starter-zipkin即可。版本使用 Spring Cloud 統(tǒng)一管理幌蚊。

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Camden.SR5</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
...
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>

使用環(huán)境變量谤碳,或者直接在 application.propertiesapplication.ymlbootstrap.yml 配置文件中配置必要的屬性溢豆。

spring.zipkin.baseUrl=http://zipkin.host.com:9411/
spring.sleuth.sampler.percentage=1.0

至此蜒简,Spring Boot 程序就可以把訪問(wèn)記錄到 Zipkin 服務(wù)器中。

有些時(shí)候漩仙,譬如搓茬,訪問(wèn)第三方 API,或者數(shù)據(jù)庫(kù)操作等場(chǎng)合队他,我們也希望在其中添加一些調(diào)用信息卷仑。那么可以手工插入一些代碼來(lái)實(shí)現(xiàn)(俗稱“埋點(diǎn)”)。

首先麸折,在需要添加的類中注入Tracer锡凝。

import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.Tracer;
...
@Autowired
private Tracer tracer;

然后,在調(diào)用之前垢啼,插入代碼窜锯。

// 創(chuàng)建一個(gè) span
final Span span = tracer.createSpan("3rd_service");
try {
  span.tag(Span.SPAN_LOCAL_COMPONENT_TAG_NAME, "3rd_service");
  span.logEvent(Span.CLIENT_SEND);
  // 這里時(shí)調(diào)用第三方 API 的代碼
} finally {
  ...
}

最后,在調(diào)用之后的 finally 中(確保異常后也被調(diào)用到)芭析,插入代碼锚扎。

span.tag(Span.SPAN_PEER_SERVICE_TAG_NAME, "3rd_service");
span.logEvent(Span.CLIENT_RECV);
tracer.close(span);

通過(guò)埋點(diǎn)我們可以生成任意詳細(xì)的調(diào)用記錄,我們就可以看到哪里還欠缺監(jiān)控馁启,需要手工埋點(diǎn)工秩;哪里調(diào)用時(shí)間過(guò)長(zhǎng),是影響性能的瓶頸进统;以及哪些調(diào)用可以并行,優(yōu)化性能降低響應(yīng)時(shí)間浪听。

image.png

image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末螟碎,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子迹栓,更是在濱河造成了極大的恐慌掉分,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異酥郭,居然都是意外死亡华坦,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門(mén)不从,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)惜姐,“玉大人,你說(shuō)我怎么就攤上這事椿息〈踉” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵寝优,是天一觀的道長(zhǎng)条舔。 經(jīng)常有香客問(wèn)我,道長(zhǎng)乏矾,這世上最難降的妖魔是什么孟抗? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮钻心,結(jié)果婚禮上凄硼,老公的妹妹穿的比我還像新娘。我一直安慰自己扔役,他們只是感情好帆喇,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著亿胸,像睡著了一般坯钦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上侈玄,一...
    開(kāi)封第一講書(shū)人閱讀 49,185評(píng)論 1 284
  • 那天婉刀,我揣著相機(jī)與錄音,去河邊找鬼序仙。 笑死突颊,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的潘悼。 我是一名探鬼主播律秃,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼治唤!你這毒婦竟也來(lái)了棒动?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤宾添,失蹤者是張志新(化名)和其女友劉穎船惨,沒(méi)想到半個(gè)月后柜裸,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡粱锐,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年疙挺,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片怜浅。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡铐然,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出海雪,到底是詐尸還是另有隱情锦爵,我是刑警寧澤,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布奥裸,位于F島的核電站险掀,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏湾宙。R本人自食惡果不足惜樟氢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望侠鳄。 院中可真熱鬧埠啃,春花似錦、人聲如沸伟恶。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)博秫。三九已至潦牛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間挡育,已是汗流浹背巴碗。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留即寒,地道東北人橡淆。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像母赵,于是被迫代替她去往敵國(guó)和親逸爵。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容