學習微服務第 5 天:ServiceComb + Zipkin 原始碼解讀
今天是南方的小年
南方的小年時間為
2019年1月29日
農曆臘月廿四,星期二
小蜜蜂在此恭祝大家小年夜快樂!
^(* ̄(oo) ̄)^
SeviceComb + Zipkin 簡介
ServiceComb 是Apache的微服務頂級專案,在微服務框架中,微服務之間通過網路進行通訊,我們必須處理所有與網路相關的問題,例如延遲,超時和分割槽。隨著部署的微服務越來越多,我們需要系統監控微服務網路延遲和請求流。
上篇文章我們介紹瞭如何使用ServiceComb與Zipkin進行協同定位微服務應用的異常的微服務和具體異常函式。
本篇將介紹ServiceComb如何通過自身handler處理鏈機制支援Zipkin 微服務級別和函式級別的呼叫鏈追蹤的。
▼▼▼
ServiceComb 如何支援zipkin
ServiceComb 提供了處理鏈機制,消費端和服務端的呼叫鏈請求都會經過該處理鏈,通過擴充套件handler處理連結口,可以實現負載均衡、熔斷容錯、流量控制等能力。同樣,呼叫鏈追蹤能力也是通過擴充套件該介面實現的。
關於ServiceComb處理鏈參考 ↓↓↓
https://docs.servicecomb.io/java-chassis/zh_CN/references-handlers/intruduction.html
ServiceComb 擴充套件handler處理連結口,編寫了handler-tracing-zipkin 模組。Handler-tracing-zipkin 模組在java-chassis/handler處理鏈下,模組內容如下。
handler-tracing-zipkin模組實現追蹤呼叫鏈記錄資料和上傳追蹤資料到zipkin服務,即可支援Zipkin。
如果讀者對於使用ServiceComb對於Zipkin支援的能力還不熟悉,可參考ServiceComb官網相關文件↓↓↓
1.http://servicecomb.apache.org/docs/tracing-with-servicecomb/
2.https://servicecomb.apache.org/cn/docs/customized-tracing-with-servicecomb/
handler-tracing-zipkin模組原始碼解讀
每一次介面呼叫請求都會觸發handler鏈的處理,而在這個handler鏈當中,ServiceComb專門為Zipkin編寫了handler類ZipkinConsumerTracingHandler
和ZipkinProviderTracingHandle進行適配。下面我們來看下這兩個類。
ZipkinConsumerTracingHandler 和ZipkinProviderTracingHandler
檢視這兩個類原始碼可知,都繼承自ZipkinTracingHandler
,都只有兩個構造器。
區別在於分別向父類構造器傳遞了不同的ZipkinTracingDelegate實現。
ZipkinTracingDelegate實現分別為ZipkinConsumerDelegate和ZipkinProviderDelegate。
這兩個代理類分別封裝了對應的Zipkin請求消費和請求生產操作。下面重點看下ZipkinTracingHandler的原始碼實現。
ZipkinTracingHandler
handler類最重要的方法是handler方法,該方法接收一個Invocation物件和AsyncResponse物件(全是ServiceComb內建物件)。Invocation物件包含當前呼叫相關資訊(包括HttpServletRequest物件)。下面我們看下這個方法做了什麼事情。
handler方法執行步驟:
呼叫了tracingDelegate.createSpan(invocation)方法建立了一個span。tracingDelegate是一個ZipkinTracingDelegate物件。
呼叫當前物件的onResponse方法封裝成一個AsyncResponse物件。該物件是是一個函式式物件,在如下圖的函式體中可看到最終呼叫了tracingDelegate.onResponse(span, response, error)上傳span到Zipkin伺服器。
呼叫invocation.next()方法將生成的AsyncResponse物件傳遞給下一個handler處理。
如果在以上操作中發生異常,將呼叫tracingDelegate.onResponse(span, null, e)方法傳送帶有異常資訊的span到Zipkin伺服器。
從以上分析我們可以看到tracingDelegate十分重要,下面我們接著看這個ZipkinTracingDelegate介面到底做了什麼。
ZipkinTracingDelegate介面
如下圖,該介面定義了4個方法。

1.tracer() ,獲取對應的追蹤器
2.createSpan(), 根據Invocation物件攜帶的資訊建立對應的span
3.onResponse(),將span物件和對應的響應資訊和異常資訊上傳到Zipkin伺服器
4.name() , 區分消費操作和生產操作
該介面有兩個實現類ZipkinConsumerDelegate
,分別對應請求消費操作和請求生產操作。
下面我們可以看到兩個實現的區別。
ZipkinConsumerDelegate和ZipkinProviderDelegate
下面我們先上兩張圖片仔細對比一下,第一張是ZipkinConsumerDelegate類,第二張是ZipkinProviderDelegate類。
我們會發現它們都是用handler變數來進行相應的操作,注意這裡的handler變數在兩個類分別是不一樣的型別,ZipkinConsumerDelegate的handler變數是HttpClientHandler物件,而ZipkinProviderDelegate的hanler變數是HttpServerHandler物件。HttpClientHandler和HttpServerHandler類都是final修飾的類,不可繼承。前面我們看到建立span和傳送span都是由這兩個類來負責,那麼我們來看下這兩個物件怎麼生成的。
仔細觀察可發現↓↓↓
ZipkinConsumerDelegate構造器部分程式碼:
this.handler = HttpClientHandler.create(httpTracing, new ConsumerInvocationAdapter());
ZipkinProviderDelegate構造器部分程式碼 :
this.handler = HttpServerHandler.create(httpTracing, new ProviderInvocationAdapter());
從上面兩段構造器程式碼中可發現HttpClientHandler和HttpServerHandler在建立物件時都分別傳入ConsumerInvocationAdapter物件和ProviderInvocationAdapter物件,這兩個物件分別繼承了Zipkin的HttpClientAdapter和HttpServerAdapter抽象類,提供了屬於ServiceComb本身的客戶端資訊和服務端資訊。而Zipkin可以在不改動程式碼的情況下獲取到這些定製資訊並用於呼叫鏈追蹤。
至此,ServiceComb如何一步一步去實現zipkin分散式呼叫鏈追蹤,已經解讀完畢。
連結
參考
1.zipkin https://zipkin.io/
2.Distributed Tracing with ServiceComb and Zipkin
http://servicecomb.apache.org/docs/tracing-with-servicecomb/
3.處理鏈參考
https://docs.servicecomb.io/java-chassis/zh_CN/references-handlers/intruduction.html
4.java-chassiss使用手冊——呼叫參考
https://docs.servicecomb.io/java-chassis/zh_CN/
文末小結
本文向社群讀者從原始碼角度闡述了ServiceComb是如何支援Zipkin的。
我們也非常歡迎愛好者們向社群提問和貢獻程式碼。
下章我們將介紹 ServiceComb+SpringCloud Ribbon使用篇 。
如果在閱讀程式碼時有任何疑問想交流,歡迎掃碼加入進微信群。
期待志同道合的朋友們加入
ServiceComb的大門為你們敞開~
用心做開源,不忘初衷
Holiday is Coming
再次祝大夥兒小年快樂~
前期閱讀:
[學習微服務-第4天] ServiceComb+Zipkin
[學習微服務-第3天] ServiceComb內建高效能閘道器服務
[每天學習微服務-原始碼解讀]ServiceComb+SpringCloud Zuul
[每天學習微服務-閘道器]ServiceComb+SpringCloud Zuul
------------------------------------------
瞭解更多資訊請訪問:
官方網站 http://servicecomb.apache.org/
Github程式碼倉庫 https://github.com/apache?q=ServiceComb
趕緊點選閱讀原文閱讀相關原始碼
並給ServiceComb點個“Star”吧
↓↓↓
你點的每個好看,我都認真當成了喜歡