微服務,一般都是用複雜的、大規模分佈式集羣來實現的。微服務構建在不一樣的軟件模塊上,這些軟件模塊,有多是由不一樣的團隊開發、可能使用不一樣的編程語言來實現、有可能布在了幾千臺服務器,橫跨多個不一樣的數據中心。所以,就須要一些能夠幫助理解系統行爲、用於分析性能問題的工具。html
API網關Ocelot 做爲微服務的一個重要組件,出如今系統邊界上的一個面向API的、串行集中式的強管控服務,這裏的邊界是企業IT系統的邊界,主要起到隔離外部訪問與內部系統的做用。經過API網關對外發布的一般是OpenAPI,在它的後面有衆多的分佈式應用,如微服務、消息收發、分佈式數據庫、分佈式緩存、分佈式對象存儲、跨域調用,這些組件共同構成了繁雜的分佈式網絡。前端
當應用A發出某個請求時,其背後可能有數十個甚至更多的服務被調用,可謂是「牽一髮而動全身」。 若是將分佈式系統比做高速公路網,每一個前端的請求就至關於高速上行駛的車輛,而處理請求的應用就是高速上的收費站,在收費站上將車輛通行信息記錄成日誌,包括時間、車牌、站點、公路、價格等,若是將全部收費站上的日誌整合在一塊兒,即可以經過惟一的車牌號肯定該車的完整通行記錄;分佈式調用系統跟蹤和監控就是類比這種思想,對每一次請求進行跟蹤,進而明確每一個請求所通過的應用、耗時等信息。git
Butterfly被設計爲分佈式追蹤和APM的Server端,它將包含Collector,Storage,獨立的Web UI,並使用Open Tracing規範來設計追蹤數據。目前僅根據規範實現了Open Tracing API,後續還會兼容google的opencensus。這裏順便提下爲何咱們不用zipkin 或是Jaeger,他們只作了tracing,Butterfly比他們多一點就是同時要作metrics和預警,就是要作立體化監控系統。目前Butterfly也是在起步階段,還有很是多的功能須要開發,目前有兩個事情的優先級比較高一個應用程序進程級別的metrics,一個是後端collector和es的性能優化,歡迎各位同窗加入一塊兒開發,咱們相信經過不斷的建設,咱們.NET社區同樣能夠達到Java的高度。回想Ocelot 的發展歷程,2016年纔是到如今已經開發了2年時間,完成了3.0版本的開發,如今已是一個日趨成熟的API網關,經過API網關鏈接後面的服務,像今天和你們分享的最近我業餘時間在開發的分佈式跟蹤的支持,這項任務在一年前提出來,https://github.com/TomPallister/Ocelot/issues/19 這裏有咱們的討論,如今集成Butterfly 來實現這個功能,讓咱們的微服務可以可運維。github
Butterfly.Client.AspNetCore 爲咱們提供了在ASP.NET Core項目集成Butterfly的組件,使用很簡單,只須要在ConfigureServices
註冊Butterfly services數據庫
public void ConfigureServices(IServiceCollection services) { //your other code services.AddButterfly(option => { option.CollectorUrl = "http://localhost:9618"; option.Service = "my service"; }); }
其中http://localhost:9618 是Butterfly的服務端,提供了UI,咱們在瀏覽器經過http://localhost:9618 就能夠訪問到。編程
那麼在API網關Ocelot 中集成Butterfly 有什麼不同呢? 咱們在Ocelot項目中加入上述代碼後,咱們已經能夠在Butterfly UI上看到咱們的追蹤數據,只是數據沒有連成一條鏈。那麼咱們作集成的工做主要就是如下2點:後端
1、將追蹤數據串起來,讓咱們能夠在Butterfly UI上直觀的看到各個節點的數據api
2、Ocelot 自己須要加入到系統跟蹤的數據定義跨域
Ocelot 集成Butterfly 實現分佈式跟蹤的代碼目前尚未加入主幹,能夠在個人代碼庫的分支https://github.com/geffzhang/Ocelot/tree/Monitoring 下看到,咱們首先在Ocelot的路由配置中加入一個配置項,表示是否啓用分佈式追蹤:瀏覽器
{
"ReRoutes": [
{
"DownstreamPathTemplate": "/api/values",
"DownstreamScheme": "http",
"UpstreamPathTemplate": "/api/values",
"UpstreamHttpMethod": [ "Get" ],
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5002
}
],
"HttpHandlerOptions": {
"AllowAutoRedirect": true,
"UseCookieContainer": true,
"UseTracing": true
}
},
UseTracing 表示是否啓用分佈式追蹤,默認爲false,也就是不啓用。 而後在Ocelot.DependencyInjection.IOcelotBuilder 加個接口方法:
方法的實現也很是簡單:
主要就是加入Ocelot 自己須要加入到系統跟蹤的數據定義,實現上主要使用DiagnosticSource, 官方的文檔:https://github.com/dotnet/corefx/blob/master/src/System.Diagnostics.DiagnosticSource/src/DiagnosticSourceUsersGuide.md 。相似於asp.net core 有個 Diagnostics中間件https://github.com/aspnet/Diagnostics,主要功能是用於報告和處理ASP.NET Core中的異常和錯誤信息,以及診斷Entity Framework核心遷移錯誤。其中還有其餘幾項功能,歡迎頁,錯誤代碼頁、如404 頁等。以及一個還算不錯的日誌查看功能,這個功能也是不少人須要的功能,直接在線查看日誌。
實現了Butterfly 的接口ITracingDiagnosticListener ,經過DI 注入後Butterfly 會幫咱們註冊好。
下面咱們要把咱們的分佈式追蹤數據串起來,OpenTracing(連接:opentracing.io)經過提供平臺無關、廠商無關的API,使得開發人員可以方便的添加(或更換)追蹤系統的實現。OpenTracing正在爲全球的分佈式追蹤,提供統一的概念和數據標準。標準的中文版是咱們的MVP吳晟翻譯的,同時他也是OpenTracing的主要成員 : https://wu-sheng.gitbooks.io/opentracing-io/content/。
在廣義上,一個trace表明了一個事務或者流程在(分佈式)系統中的執行過程。在OpenTracing標準中,trace是多個span組成的一個有向無環圖(DAG),每個span表明trace中被命名並計時的連續性的執行片斷。
分佈式追蹤中的每一個組件都包含本身的一個或者多個span。例如,在一個常規的RPC調用過程當中,OpenTracing推薦在RPC的客戶端和服務端,至少各有一個span,用於記錄RPC調用的客戶端和服務端信息。
一個父級的span會顯示的並行或者串行啓動多個子span。在OpenTracing標準中,甚至容許一個子span有個多父span(例如:並行寫入的緩存,可能經過一次刷新操做寫入動做)。
因此集成的關鍵點就在tracerId和spanId的關聯關係的Id 處理上。
tracerid 表明是全局的id,相似於Ocelot的RequestId http://ocelot.readthedocs.io/en/latest/features/requestid.html,存放在http header 裏,它的key是ot-traceid,因此在Ocelot裏面能夠把全局的RequestId設置爲ot-traceid 。
同時還須要處理spanid,使得下游的的組件的spanid是它上一級的spanid,也是存放在http header 裏,它的key是ot-spanId,咱們在OcelotRequestTracer 以及OcelotHttpTracingHandler 須要處理spanid
上面咱們說完了代碼集成工做,咱們來看看效果吧,我搭了一個Demo環境,服務前端—>Ocelot –>服務後端。Butterfly爲每一個請求生成全局惟一的ID(Traceld),經過它將不一樣系統的「孤立的」調用信息關聯在一塊兒,還原出更多有價值的數據。
上圖是一條API調用請求的調用鏈,在Span列能夠看到請求中間過程所通過的一系列應用組件,能夠看到最早通過請求端的HttpClient組件,後續調用Ocelot、HttpClient、backend等,造成調用樹(樹上的縮進表示嵌套關係),從調用樹上很容易看到前端請求的完整處理過程。在上圖所示的頁面中也清晰地展現了每塊應用處理請求得具體耗時,很是直觀地進行定位;此外,點擊具體的組件,能夠看到這個組件中的日誌記錄
對於分佈式調用跟蹤系統而言,它並不只僅提供了調用鏈這一功能,由於它對全部中間件的調用作埋點,因此中間件上的全部狀況均可以監控的到。所以,在造成調用鏈的過程當中也會造成一份詳細的調用監控報表,它與其餘監控的不一樣之處在於:該監控報表是帶有上下鑽取功能的報表。由於調用鏈是詳細的底層統計,對上能夠造成的報表維度是很是豐富的,在上圖所示的調用報表裏,不只能夠看到服務的狀況,還能夠下鑽到它所調用服務的狀況;另外從監控報表上還能夠進行調用鏈的下鑽,查看清晰的調用鏈信息。目前Butterfly這塊功能也是須要繼續開發的功能,歡迎各位同窗一塊兒加入開發。
還有鏈路分析,鏈路與調用鏈不一樣,鏈路是一個統計學的概念,而調用鏈是單體調用的過程。分析鏈路的拓撲形態分析:分析來源、去向,識別不合理來源;
上圖是全局調用拓撲圖,能夠明顯的看到不一樣的服務之間存在複雜的調用關係,也能夠查看某個服務和其餘服務之間的調用關係以及調用的頻次; 經過該拓撲圖,架構師能夠清楚地觀察到系統上的調用狀況。