隨着業務發展,系統拆分導致系統調用鏈路愈發復雜一個前端請求可能最終需要調用很多次后端服務才能完成,當整個請求變慢或不可用時,我們是無法得知該請求是由某個或某些后端服務引起的,這時就需要解決如何快讀定位服務故障點,以對症下葯。於是就有了分布式系統調用跟蹤的誕生。
針對微服務化應用鏈路追蹤的問題,Google在2010年發表了論文《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》,這篇文章是業內實現鏈路追蹤的標桿和理論基礎,具有非常大的參考價值。目前鏈路追蹤組件主要有Google的Dapper,Twitter 的Zipkin,以及阿里的Eagleeye (鷹眼)等,它們都是非常優秀的鏈路追蹤開源組件。
Spring Cloud Sleuth是 Spring Cloud為分布式服務鏈路跟蹤提供的解決方案。它提供以下功能:
- 提供鏈路追蹤。通過sleuth可以很清楚的看出一個請求都經過了哪些服務;可以很方便的理清服務間的調用關系。
- 可視化錯誤。對於程序未捕捉的異常,可以結合zipkin分析。
- 分析耗時。通過sleuth可以很方便的看出每個采樣請求的耗時,分析出哪些服務調用比較耗時。當服務調用的耗時隨着請求量的增大而增大時,也可以對服務的擴容提供一定的提醒作用。
- 優化鏈路。對於調用頻繁的服務,可以並行調用或針對業務做一些優化措施等。
Spring Cloud Sleuth可以追蹤以下類型的組件:async,hystrix,messaging,websocket,rxjava,scheduling,web(SpringWebMvc,Spring WebFlux, Servlet),webclient(Spring RestTemplate),feign,zuul。
web
webflux通過注冊TraceWebFilter, webmvc通過實現HandlerInterceptorAdapter,Servlet通過定義AOP切面對@RestController、@Controller、Callable對請求進行trace攔截,完成span的新建、傳遞和銷毀。可以設置spring.sleuth.web.enabled為false禁用所有web請求的sleuth跟蹤。
async
通過TraceAsyncAspect對@Async注解進行攔截,通過 TraceRunnable 和 TraceCallable來對runnable和callable進行包裝和利用LazyTraceExecutor來代替java的Executor。Spring Cloud Sleuth利用以上方式進行span的新建和銷毀。
如果需要禁用的話,可以設置spring.sleuth.async.enabled為false。如果禁用,與異步相關的機制就不會發生。
hystrix
原理是使用HystrixPlugins添加trace相關的plugin,自定義了一個HystrixConcurrencyStrategy子類SleuthHystrixConcurrencyStrategy 。若需要禁用可以設置spring.sleuth.hystrix.strategy.enable為false。
messaging
Spring Cloud Sleuth提供了TracingChannelInterceptor,是基於Spring message的ChannelInterceptorAdapter/ExecutorChannelInterceptor,它發布/訂閱事件都是會進行span的新建和銷毀的。可以設置spring.sleuth.integration.enabled為false禁用該機制。
websocket
將TracingChannelInterceptor攔截類注冊到ChannelRegistration中進行trace攔截。
rxjava
通過自定義RxJavaSchedulersHook的子類SleuthRxJavaSchedulersHook,它使用TraceAction來包裝實例中Action0。這個鈎子對象,會根據之前調度的Action是否已經開始跟蹤,來決定是創建還是延續使用span。可以通過設置spring.sleuth.rxjava.schedulers.hook.enabled為false來關閉這個對象的使用。可以定義一組正則表達式來對線程名進行過濾,來選擇哪些線程不需要跟蹤。
scheduling
原理是建立TraceSchedulingAspect 切面對Scheduled注解進行trace攔截,對span進行創建和銷毀。可以通過設置spring.sleuth.scheduled.enabled為false來使該切面無效。
feign
Spring Cloud Sleuth默認通過TraceFeignClientAutoConfiguration提供feign的集成,可以設置spring.sleuth.feign.enabled為false來使其無效。
zuul
注冊Zuul過濾器TracePostZuulFilter來傳遞tracing信息(請求頭使用tracing數據填滿),可以設置spring.sleuth.zuul.enabled為false來關閉Zuul服務。