在分布式服務(wù)架構(gòu)中栽烂,需要對分布式服務(wù)進(jìn)行治理——在分布式服務(wù)協(xié)同向用戶提供服務(wù)時(shí),每個(gè)請求都被哪些服務(wù)處理恋脚?在遇到問題時(shí)腺办,在調(diào)用哪個(gè)服務(wù)上發(fā)生了問題?在分析性能時(shí)糟描,調(diào)用各個(gè)服務(wù)都花了多長時(shí)間怀喉?哪些調(diào)用可以并行執(zhí)行?…… 為此船响,分布式服務(wù)平臺就需要提供這樣一種基礎(chǔ)服務(wù)——可以記錄每個(gè)請求的調(diào)用鏈躬拢;調(diào)用鏈上調(diào)用每個(gè)服務(wù)的時(shí)間;各個(gè)服務(wù)之間的拓?fù)潢P(guān)系…… 我們把這種行為稱為“分布式服務(wù)跟蹤”见间。(了解源碼可+求求: 1791743380)
1. 背景
現(xiàn)今業(yè)界分布式服務(wù)跟蹤的理論基礎(chǔ)主要來自于 Google 的一篇論文《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》聊闯,使用最為廣泛的開源實(shí)現(xiàn)是 Twitter 的 Zipkin,為了實(shí)現(xiàn)平臺無關(guān)米诉、廠商無關(guān)的分布式服務(wù)跟蹤菱蔬,CNCF 發(fā)布了布式服務(wù)跟蹤標(biāo)準(zhǔn) Open Tracing。國內(nèi)史侣,淘寶的“鷹眼”拴泌、京東的“Hydra”、大眾點(diǎn)評的“CAT”惊橱、新浪的“Watchman”蚪腐、唯品會的“Microscope”、窩窩網(wǎng)的“Tracing”都是這樣的系統(tǒng)税朴。
2. Spring Cloud Sleuth
一般的回季,一個(gè)分布式服務(wù)跟蹤系統(tǒng)家制,主要有三部分:數(shù)據(jù)收集、數(shù)據(jù)存儲和數(shù)據(jù)展示泡一。根據(jù)系統(tǒng)大小不同慰丛,每一部分的結(jié)構(gòu)又有一定變化。譬如瘾杭,對于大規(guī)模分布式系統(tǒng),數(shù)據(jù)存儲可分為實(shí)時(shí)數(shù)據(jù)和全量數(shù)據(jù)兩部分哪亿,實(shí)時(shí)數(shù)據(jù)用于故障排查(troubleshooting)粥烁,全量數(shù)據(jù)用于系統(tǒng)優(yōu)化;數(shù)據(jù)收集除了支持平臺無關(guān)和開發(fā)語言無關(guān)系統(tǒng)的數(shù)據(jù)收集蝇棉,還包括異步數(shù)據(jù)收集(需要跟蹤隊(duì)列中的消息讨阻,保證調(diào)用的連貫性),以及確保更小的侵入性篡殷;數(shù)據(jù)展示又涉及到數(shù)據(jù)挖掘和分析钝吮。雖然每一部分都可能變得很復(fù)雜,但基本原理都類似板辽。
服務(wù)追蹤的追蹤單元是從客戶發(fā)起請求(request)抵達(dá)被追蹤系統(tǒng)的邊界開始奇瘦,到被追蹤系統(tǒng)向客戶返回響應(yīng)(response)為止的過程,稱為一個(gè)“trace”劲弦。每個(gè) trace 中會調(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ù)的過程中轴踱,會不斷地有請求和響應(yīng)發(fā)生症脂,也就會不斷生成 trace,把這些帶有span 的 trace 記錄下來寇僧,就可以描繪出一幅系統(tǒng)的服務(wù)拓?fù)鋱D摊腋。附帶上 span 中的響應(yīng)時(shí)間,以及請求成功與否等信息嘁傀,就可以在發(fā)生問題的時(shí)候兴蒸,找到異常的服務(wù);根據(jù)歷史數(shù)據(jù)细办,還可以從系統(tǒng)整體層面分析出哪里性能差橙凳,定位性能優(yōu)化的目標(biāo)蕾殴。
Spring Cloud Sleuth為服務(wù)之間調(diào)用提供鏈路追蹤。通過Sleuth可以很清楚的了解到一個(gè)服務(wù)請求經(jīng)過了哪些服務(wù)岛啸,每個(gè)服務(wù)處理花費(fèi)了多長钓觉。從而讓我們可以很方便的理清各微服務(wù)間的調(diào)用關(guān)系。此外Sleuth可以幫助我們:
耗時(shí)分析: 通過Sleuth可以很方便的了解到每個(gè)采樣請求的耗時(shí)坚踩,從而分析出哪些服務(wù)調(diào)用比較耗時(shí);
可視化錯誤: 對于程序未捕捉的異常荡灾,可以通過集成Zipkin服務(wù)界面上看到;
鏈路優(yōu)化: 對于調(diào)用比較頻繁的服務(wù),可以針對這些服務(wù)實(shí)施一些優(yōu)化措施瞬铸。
spring cloud sleuth可以結(jié)合zipkin批幌,將信息發(fā)送到zipkin,利用zipkin的存儲來存儲信息嗓节,利用zipkin ui來展示數(shù)據(jù)荧缘。
2. ZipKin
Zipkin 是一個(gè)開放源代碼分布式的跟蹤系統(tǒng),由Twitter公司開源拦宣,它致力于收集服務(wù)的定時(shí)數(shù)據(jù)截粗,以解決微服務(wù)架構(gòu)中的延遲問題,包括數(shù)據(jù)的收集鸵隧、存儲绸罗、查找和展現(xiàn)。
每個(gè)服務(wù)向zipkin報(bào)告計(jì)時(shí)數(shù)據(jù)豆瘫,zipkin會根據(jù)調(diào)用關(guān)系通過Zipkin UI生成依賴關(guān)系圖从诲,顯示了多少跟蹤請求通過每個(gè)服務(wù),該系統(tǒng)讓開發(fā)者可通過一個(gè) Web 前端輕松的收集和分析數(shù)據(jù)靡羡,例如用戶每次請求服務(wù)的處理時(shí)間等系洛,可方便的監(jiān)測系統(tǒng)中存在的瓶頸。
Zipkin提供了可插拔數(shù)據(jù)存儲方式:In-Memory略步、MySql描扯、Cassandra以及Elasticsearch。接下來的測試為方便直接采用In-Memory方式進(jìn)行存儲趟薄,生產(chǎn)推薦Elasticsearch绽诚。
3. 快速上手
3.1 zipkin
3.1.1 zipkin下載
根據(jù)全球最大同性交友網(wǎng)站(github)搜索zipkin后發(fā)現(xiàn),zipkin現(xiàn)在已經(jīng)不在推薦使用maven引入jar的方式構(gòu)建了杭煎,目前推薦的方案是直接down他們打好包的jar恩够,用java -jar的方式啟動,傳送門在這里:https://github.com/openzipkin/zipkin羡铲。
The quickest way to get started is to fetch the latest released server as a self-contained executable jar. Note that the Zipkin server requires minimum JRE 8. For example:
curl -sSL https://zipkin.io/quickstart.sh | bash -s
java -jar zipkin.jar
You can also start Zipkin via Docker.
docker run -d -p 9411:9411 openzipkin/zipkin
Once the server is running, you can view traces with the Zipkin UI at?http://your_host:9411/zipkin/.
If your applications aren’t sending traces, yet, configure them with Zipkin instrumentation or try one of our examples.
Check out the zipkin-server documentation for configuration details, or docker-zipkin for how to use docker-compose.
以上內(nèi)容來自zipkin官方github摘錄蜂桶。簡單解釋就是可以使用https下載的方式下載zipkin.jar,并使用java -jar的方式啟動也切,還有一種就是使用docker的方式進(jìn)行啟動扑媚。
具體搭建過程我這里就不在贅述腰湾,有不懂的可以私信或者關(guān)注公眾號留言問我。
3.1.2 zipkin啟動
zipkin的啟動命令就比較謎了疆股。
最簡單的啟動命令為:nohup java -jar zipkin.jar >zipkin.out 2>&1 &费坊,這時(shí),我們使用的是zipkin的In-Memory旬痹,含義是所有的數(shù)據(jù)都保存在內(nèi)存中附井,一旦重啟數(shù)據(jù)將全部清空,這肯定不是我們想要的两残,我們更想數(shù)據(jù)可以保存在磁盤中羡忘,可以被抽取到大數(shù)據(jù)平臺上,方便我們后續(xù)的相關(guān)性能磕昼、服務(wù)狀態(tài)分析、實(shí)時(shí)報(bào)警等功能节猿。
這里我把使用mysql的啟動語句分享出來票从,有關(guān)ES的啟動語句基本相同:
STORAGE_TYPE=mysql MYSQL_DB=zipkin MYSQL_USER=name MYSQL_PASS=password MYSQL_HOST=172.19.237.44 MYSQL_TCP_PORT=3306 MYSQL_USE_SSL=false nohup java -jar zipkin.jar --zipkin.collector.rabbitmq.addresses=localhost --zipkin.collector.rabbitmq.username=username --zipkin.collector.rabbitmq.password=password --logging.level.zipkin2=DEBUG >zipkin.out 2>&1 &
注意:?因?yàn)殒溌纷粉櫟臄?shù)據(jù)上報(bào)量是非常大的,如果上報(bào)數(shù)據(jù)直接使用http請求的方式推送到zipkin中滨嘱,很有可能會把zipkin服務(wù)或者數(shù)據(jù)庫沖崩掉峰鄙,所以我在這里增加了rabbitmq的相關(guān)配置,上報(bào)數(shù)據(jù)先推送至rabbitmq中太雨,再由rabbitmq講數(shù)據(jù)推送至zipkin服務(wù),這樣達(dá)到一個(gè)請求削峰填谷的作用囊扳。
有關(guān)zipkin的啟動命令可以配置的參數(shù)可以看這里:https://github.com/apache/incubator-zipkin/tree/master/zipkin-server
有關(guān)zipkin配置mysql基礎(chǔ)建表語句可以看這里:https://github.com/apache/incubator-zipkin/blob/master/zipkin-storage/mysql-v1/src/main/resources/mysql.sql
有關(guān)zipkin本身配置文件可以看這里:https://github.com/apache/incubator-zipkin/blob/master/zipkin-server/src/main/resources/zipkin-server-shared.yml
至此,zipkin服務(wù)應(yīng)該已經(jīng)搭建并完成锥咸,現(xiàn)在我們可以訪問一下默認(rèn)端口,看一下zipkin-ui具體長什么樣子了搏予。
3.2 Spring Cloud Sleuth 使用
我們先將上一篇用到的zuul-simple熊锭、Eureka和producer copy到本篇文章使用的文件夾中雪侥。
3.2.1 增加依賴:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-stream-rabbit</artifactId> </dependency>
在zuul-simple和producer兩個(gè)項(xiàng)目中增加sleuth和rabbitmq的依賴。
3.2.2 配置文件
增加有關(guān)rabbitmq和sleuth的配置速缨,這里我僅給出zuul的配置文件锌妻,producer的配置同理。
server:? port:8080spring:? application:? ? name:spring-cloud-zuul? rabbitmq:? ? host:host? ? port:port? ? username:username? ? password:password? sleuth:? ? sampler:? ? ? probability:1.0zuul:? FormBodyWrapperFilter:? ? pre:? ? ? disable:trueeureka:? client:? ? service-url:? ? ? defaultZone:http://localhost:8761/eureka/
注:spring.sleuth.sampler.probability的含義是鏈路追蹤采樣率旬牲,默認(rèn)是0.1从祝,我這里為了方便測試,將其改成1.0牍陌,意思是百分之百采樣。
3.2.3 測試
這里我們依次啟動Eureka贮预、producer和zuul-simple契讲。
打開瀏覽器仿吞,訪問測試連接:http://localhost:8080/spring-cloud-producer/hello?name=spring&token=123
這時(shí)我們先看zuul的日志捡偏,如下圖:
2019-07-07 23:09:28.529? INFO [spring-cloud-zuul,0596a362d604fb01,0596a362d604fb01,true] 20648 --- [nio-8080-exec-1] c.s.zuulsimple.filter.TokenFilter
注:這里的0596a362d604fb01就是這個(gè)請求的traceID,0596a362d604fb01是spanID你虹。
我們打開zipkin-ui的界面彤避,如下圖:
這里我們可以看到這個(gè)請求的整體耗時(shí),點(diǎn)擊這個(gè)請求董饰,可以進(jìn)入到詳情頁面,查看每個(gè)服務(wù)的耗時(shí):
點(diǎn)擊對應(yīng)的服務(wù)卒暂,我們可以看到相應(yīng)的訪問時(shí)間娄帖,http請求類型、路徑齿坷、IP、tranceID永淌、spanId等內(nèi)容佩耳,如下圖: