導讀:有一天咱們接到這樣一條客訴「大家的收銀軟件最近特別慢,嚴重影響咱們的收銀效率,再不解決咱們就不用了」,我相信你們應該都遇到過這種問題,即便如今沒遇到,未來必定會遇到的,那遇到了怎麼辦呢?就這個話題咱們今天一塊兒來聊一聊。html
關鍵詞:分佈式,鏈路追蹤git
靠人終究靠不住github
不知道你們是怎麼處理開頭提到的那種問題的呢?最簡單粗暴的辦法就是把相關人員集中到一個會議室裏面對數據,怎麼對呢?web
客戶端開發人員:我查了日誌,客戶端的請求過程一共用了5s,請求是從幾點幾分幾秒發起的,大家查下服務端的日誌;spring
交易系統開發人員:我這邊是幾點幾分幾秒收到的請求,交易系統一共花了4s多一些,其中調用支付網關花了將近4s,網關那邊看下日誌吧;docker
網關開發人員:我這邊是幾點幾分幾秒收到的請求,網關一共花了3s多一點,大部分時間都花在了調用第三方上;後端
估計大多數人最開始都是這麼處理此類問題的,簡單粗暴。但若是三天兩頭給你來這麼一會兒你還受得了嗎?天天給你幾百個上千個訂單號讓你對數據,你還能抽時間寫代碼嗎?估計連帶薪上廁所的時間都沒了吧。最後這個問題可能傳到了領導那裏,領導通常喜歡要全局報表數據,你怎麼給他出這個報表?是否是一籌莫展,忽然有點想換工做了,哈哈。咱們還真是接到過這種需求,一堆人在那裏awk而後就沒有而後了。網絡
「當一件事情成爲一件常態,那意味着咱們可能須要一件工具來解放本身了,靠人終究是靠不住的」,就在這種背景之下咱們決定引入一個調用鏈追蹤的工具來解放咱們,也就是今天的主角jaeger。關於jaeger的說明網上不少,推薦去官網系統的瞭解一下 https://www.jaegertracing.io,我這裏只是把搭建過程和使用上的一些心得分享出來和你們一塊兒交流。架構
jaeger架構
mvc
直接引入一張官網的圖
jaeger組件介紹:
jaeger-client:jaeger 的客戶端,實現了opentracing協議;
jaeger-agent:jaeger client的一個代理程序,client將收集到的調用鏈數據發給agent,而後由agent發給collector;
jaeger-collector:負責接收jaeger client或者jaeger agent上報上來的調用鏈數據,而後作一些校驗,好比時間範圍是否合法等,最終會通過內部的處理存儲到後端存儲;
jaeger-query:專門負責調用鏈查詢的一個服務,有本身獨立的UI;
jaeger-ingester:中文名稱「攝食者」,可用從kafka讀取數據而後寫到jaeger的後端存儲,好比Cassandra和Elasticsearch;
spark-job:基於spark的運算任務,能夠計算服務的依賴關係,調用次數等;
其中jaeger-collector和jaeger-query是必須的,其他的都是可選的,咱們沒有采用agent上報的方式,而是讓客戶端直接經過endpoint上報到collector。
搭建jaeger
由於咱們的應用服務都是採用容器部署的,因此咱們的jaeger服務也沿用以往的風格。
docker啓動jaeger-collector
docker run -d --rm -p 14268:14268 -p 14269:14269 -e SPAN_STORAGE_TYPE=elasticsearch -e ES_SERVER_URLS=http://10.200.46.229:9200 jaegertracing/jaeger-collector:1.11
docker啓動jaeger-query
docker run -d --rm -p 16686:16686 -p 16687:16687 -e SPAN_STORAGE_TYPE=elasticsearch -e ES_SERVER_URLS=http://10.200.46.229:9200 jaegertracing/jaeger-query:1.11
應用程序接入
接下來就是如何讓調用鏈條上的各端接入了,這裏只須要把握一個原則就好,「儘可能讓接入方無感知,沒有侵入性」,這裏簡單說下咱們的接入方式:
- 客戶端接入:客戶端採用okhttp 攔截器的方式接入,使用請求頭傳遞trace上下文,這裏還能夠和okhttp 的EventListener配合起來獲取一些網絡層面的指標,好比dns解析時間,鏈接發起時間等等;
- web程序接入:web端採用springmvc攔截器方式接入,從http請求頭裏面來提取trace上下文,而後基於上下文構建一個springmvc的span,記得在請求結束的時候finish奧,不然調用鏈數據可能會長這樣:
- RPC框架如何集成:通常RPC框架都會提供一些擴展點讓使用者來作一些框架集成的事情,拿dubbo來講能夠採用Filter和隱示傳參的方式來實現請求上下文的傳遞;
- 外部調用如何集成:有一些調用是基於sdk或者httpclient調用的,這類調用咱們如何植入調用鏈的邏輯呢?這裏不得不佩服AspectJ的強大了,爲了不你少走彎路我還會推薦你去了解一下「spectj-maven-plugin」這個maven插件,什麼?不是基於spring的那一堆註解就能夠了嗎,爲何還要引入maven來幹這事。估計你還須要去了解一下運行期植入和編譯器植入的相關概念以及適用場景。
具體你要把Span包裝成什麼樣就靠你自由發揮了,可是不要太離譜,建議參考下這個https://opentracing.io/docs/overview/spans/。
上線
上線前問本身幾個問題,個人攔截器寫的是否健壯,拋異常了不會影響正常調用吧?是否須要評估一下數據量?別一上線把後端存儲打死了。
使用jaeger-quey來檢索調用鏈
- 先選擇一個service而後針對這個service作一些複雜的檢索,好比針對某個標籤,操做的耗時等;
2.若是有知足條件的數據右邊會展現出結果
上面圖中分別展現了兩條支付的調用鏈路,一條成功了,一條失敗了,你可能會問:jaeger是怎麼判斷成功失敗的呢?簡單來講就是經過特殊的標籤,直接甩給你一篇opentracing的文檔看完就懂了 https://github.com/opentracing/specification/blob/master/semantic_conventions.md。
3.查看調用鏈詳情
4.查看依賴關係,以及調用次數
也許你服務也搭好了,調用鏈數據也看到了,但就是看不到這個調用關係圖,別急你去這溜達一圈就知道了https://www.jaegertracing.io/docs/1.11/faq/。
好吧,今天就到這,大週六的晚上抽一點時間來梳理一下最近的工做,還但願對各位有一點點的幫助。
原文出處:https://www.cnblogs.com/chopper-poet/p/10743141.html