springcloud-sleuth源碼解析1-初始化

基於spring cloud 1.2.1版本java

spring cloud的基礎是spring boot,而spring boot能夠零配置初始化spring。當咱們引入spring-cloud-starter-sleuth依賴的時候,會附帶spring-cloud-sleuth-core依賴。spring boot掃描spring-cloud-sleuth-core依賴下的spring.factories文件,以下:web

# Auto Configuration
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration,\
org.springframework.cloud.sleuth.metric.TraceMetricsAutoConfiguration,\
org.springframework.cloud.sleuth.log.SleuthLogAutoConfiguration,\
org.springframework.cloud.sleuth.instrument.messaging.TraceSpanMessagingAutoConfiguration,\
org.springframework.cloud.sleuth.instrument.messaging.TraceSpringIntegrationAutoConfiguration,\
org.springframework.cloud.sleuth.instrument.messaging.websocket.TraceWebSocketAutoConfiguration,\
org.springframework.cloud.sleuth.instrument.async.AsyncCustomAutoConfiguration,\
org.springframework.cloud.sleuth.instrument.async.AsyncDefaultAutoConfiguration,\
org.springframework.cloud.sleuth.instrument.hystrix.SleuthHystrixAutoConfiguration,\
org.springframework.cloud.sleuth.instrument.scheduling.TraceSchedulingAutoConfiguration,\
org.springframework.cloud.sleuth.instrument.web.TraceHttpAutoConfiguration,\
org.springframework.cloud.sleuth.instrument.web.TraceWebAutoConfiguration,\
org.springframework.cloud.sleuth.instrument.web.client.TraceWebClientAutoConfiguration,\
org.springframework.cloud.sleuth.instrument.web.client.TraceWebAsyncClientAutoConfiguration,\
org.springframework.cloud.sleuth.instrument.web.client.feign.TraceFeignClientAutoConfiguration,\
org.springframework.cloud.sleuth.instrument.zuul.TraceZuulAutoConfiguration,\
org.springframework.cloud.sleuth.instrument.rxjava.RxJavaAutoConfiguration,\
org.springframework.cloud.sleuth.annotation.SleuthAnnotationAutoConfiguration

# Environment Post Processor
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.cloud.sleuth.autoconfig.TraceEnvironmentPostProcessor

這些是自動裝配bean的javaConfig,下面首先分析TraceAutoConfiguration。spring

TraceAutoConfiguration

@Configuration
@ConditionalOnProperty(value="spring.sleuth.enabled", matchIfMissing=true)
@EnableConfigurationProperties({TraceKeys.class, SleuthProperties.class})
public class TraceAutoConfiguration {
	@Autowired
	SleuthProperties properties;

	@Bean
	@ConditionalOnMissingBean
	public Random randomForSpanIds() {
		return new Random();
	}

	@Bean
	@ConditionalOnMissingBean
	public Sampler defaultTraceSampler() {
		return NeverSampler.INSTANCE;
	}

	@Bean
	@ConditionalOnMissingBean(Tracer.class)
	public DefaultTracer sleuthTracer(Sampler sampler, Random random,
			SpanNamer spanNamer, SpanLogger spanLogger,
			SpanReporter spanReporter, TraceKeys traceKeys) {
		return new DefaultTracer(sampler, random, spanNamer, spanLogger,
				spanReporter, this.properties.isTraceId128(), traceKeys);
	}

	@Bean
	@ConditionalOnMissingBean
	public SpanNamer spanNamer() {
		return new DefaultSpanNamer();
	}

	@Bean
	@ConditionalOnMissingBean
	public SpanReporter defaultSpanReporter() {
		return new NoOpSpanReporter();
	}

	@Bean
	@ConditionalOnMissingBean
	public SpanAdjuster defaultSpanAdjuster() {
		return new NoOpSpanAdjuster();
	}

}

@Configuration與@Bean結合起來使用能夠以javaConfig方式生成bean,@Bean annotation下面的方法會生成一個bean,方法名爲bean的name,而入參則是建立該bean依賴的的ref bean。
@ConditionalOnProperty(value="spring.sleuth.enabled", matchIfMissing=true)註解的意思是該類生成bean須要的條件,這裏條件是當spring.sleuth.enabled爲true時(沒有設置默認爲true即條件符合,也就是顯式設置爲false纔算不符合條件),纔會觸發生成bean。spring.sleuth.enabled的值在SleuthProperties中設置的,它會讀取配置文件中以spring.sleuth爲前綴的信息並設置到field中,好比enabled等。apache

@ConfigurationProperties("spring.sleuth")
public class SleuthProperties {

	private boolean enabled = true;
	/** When true, generate 128-bit trace IDs instead of 64-bit ones. */
	private boolean traceId128 = false;

	public boolean isEnabled() {
		return this.enabled;
	}

	public void setEnabled(boolean enabled) {
		this.enabled = enabled;
	}

	public boolean isTraceId128() {
		return this.traceId128;
	}

	public void setTraceId128(boolean traceId128) {
		this.traceId128 = traceId128;
	}
}

@EnableConfigurationProperties({TraceKeys.class, SleuthProperties.class})註解則是支持將@ConfigurationProperties註解的bean註冊到本類當中,這裏是將TraceKey、SleuthProperties對應的bean註冊到本類當中。websocket

下面分析每一個@Bean annotaded method,首先解釋下@ConditionalOnMissingBean的含義。它的意思很明顯,就是當不存在該類型的bean時纔會觸發。若是在其餘地方定義了此類型的bean,那就不會執行該方法產生bean了。mvc

  1. randomForSpanIds
    生成一個類型爲Random,名稱爲randomForSpanIds的bean,此bean做用是爲後續生成span id而建立的一個id生成器。
  2. defaultTraceSampler
    生成一個默認的trace採集器bean,該採集器爲NeverSampler.INSTANCE,意思就是永遠不採集。
  3. sleuthTracer
    生成一個DefaultTracer類型的trace bean,並將依賴的一些bean注入。該bean的主要做用就是建立span以及其餘操做。
  4. spanNamer
    span名稱生成器,這裏返回一個DefaultSpanNamer類型的bean,可以實現經過SpanName註解設置span name。
  5. defaultSpanReporter
    span的上報器,好比將span上報給zipkin。這裏返回一個NoOpSpanReporter類型的bean,即不作上報操做。
  6. defaultSpanAdjuster
    span的調整器,在span上報以前能夠作一些調整。這裏返回一個NoOpSpanAdjuster類型的bean,即不作任何調整。

sleuth的基礎config分析完後,下面分析instrumnet的配置,即如何在應用中織入trace埋點的配置。app

instrumnet

正經常使用到的trace span有三種類型:dom

  1. 做爲server端接收請求、響應請求的span
  2. 做爲client端發送請求、接收響應的span
  3. 做爲本地模塊代碼塊執行的span

一、2中的span屬於remote span,而3中的span屬於local span。異步

Web

好的,下面分析web的基礎配置,也就是涉及到跨節點的trace配置。socket

TraceHttpAutoConfiguration

@Configuration
@ConditionalOnBean(Tracer.class)
@AutoConfigureAfter(TraceAutoConfiguration.class)
@EnableConfigurationProperties({ TraceKeys.class, SleuthWebProperties.class })
public class TraceHttpAutoConfiguration {

	@Bean
	@ConditionalOnMissingBean
	public HttpTraceKeysInjector httpTraceKeysInjector(Tracer tracer, TraceKeys traceKeys) {
		return new HttpTraceKeysInjector(tracer, traceKeys);
	}

	@Bean
	@ConditionalOnMissingBean
	public HttpSpanExtractor httpSpanExtractor(SleuthWebProperties sleuthWebProperties) {
		return new ZipkinHttpSpanExtractor(Pattern.compile(sleuthWebProperties.getSkipPattern()));
	}

	@Bean
	@ConditionalOnMissingBean
	public HttpSpanInjector httpSpanInjector() {
		return new ZipkinHttpSpanInjector();
	}
}

@ConditionalOnBean(Tracer.class)意思是當存在Trace bean的時候纔會觸發。
@AutoConfigureAfter(TraceAutoConfiguration.class)意思是在TraceAutoConfiguration處理完後再觸發。
@EnableConfigurationProperties({ TraceKeys.class, SleuthWebProperties.class })意思是將TraceKey、SleuthWebProperties對應的config注入到該類中,以便後期直接使用這些java config對象。

  1. httpTraceKeysInjector
    該bean主要功能是把http請求相關信息(好比request path、url、method等)添加到span中。
  2. httpSpanExtractor
    從http請求中提取trace信息(好比traceId,parent spanId等),根據提取的信息生成span,若是http請求中不存在trace信息,則會生成一個新的span。生成的span可能做爲一個rpc請求的parent span。好比服務接受一個http請求,生成一個span a,而後內部經過rpc調用其餘服務,這時候生成一個新的span b。span b的parent span就是 span a。
  3. httpSpanInjector
    該bean的做用是在client sent的時候也就是客戶端發送請求的時候在request中(好比http request的head中)注入trace的相關信息,將相關信息傳遞到客戶端請求的服務端。

TraceWebAutoConfiguration

前面分析的TraceHttpAutoConfiguration生成的bean只是一些核心基礎的bean,但沒有具體應用到web服務當中。而此類會進行相關配置。

@Configuration
@ConditionalOnProperty(value = "spring.sleuth.web.enabled", matchIfMissing = true)
@ConditionalOnWebApplication
@ConditionalOnBean(Tracer.class)
@AutoConfigureAfter(TraceHttpAutoConfiguration.class)
public class TraceWebAutoConfiguration {

	/**
	 * Nested config that configures Web MVC if it's present (without adding a runtime
	 * dependency to it)
	 */
	@Configuration
	@ConditionalOnClass(WebMvcConfigurerAdapter.class)
	@Import(TraceWebMvcConfigurer.class)
	protected static class TraceWebMvcAutoConfiguration {
	}

	@Bean
	public TraceWebAspect traceWebAspect(Tracer tracer, TraceKeys traceKeys,
			SpanNamer spanNamer) {
		return new TraceWebAspect(tracer, spanNamer, traceKeys);
	}

	@Bean
	@ConditionalOnClass(name = "org.springframework.data.rest.webmvc.support.DelegatingHandlerMapping")
	public TraceSpringDataBeanPostProcessor traceSpringDataBeanPostProcessor(
			BeanFactory beanFactory) {
		return new TraceSpringDataBeanPostProcessor(beanFactory);
	}

	@Bean
	public FilterRegistrationBean traceWebFilter(TraceFilter traceFilter) {
		FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(
				traceFilter);
		filterRegistrationBean.setDispatcherTypes(ASYNC, ERROR, FORWARD, INCLUDE,
				REQUEST);
		filterRegistrationBean.setOrder(TraceFilter.ORDER);
		return filterRegistrationBean;
	}

	@Bean
	public TraceFilter traceFilter(Tracer tracer, TraceKeys traceKeys,
			SkipPatternProvider skipPatternProvider, SpanReporter spanReporter,
			HttpSpanExtractor spanExtractor,
			HttpTraceKeysInjector httpTraceKeysInjector) {
		return new TraceFilter(tracer, traceKeys, skipPatternProvider.skipPattern(),
				spanReporter, spanExtractor, httpTraceKeysInjector);
	}

	@Configuration
	@ConditionalOnClass(ManagementServerProperties.class)
	@ConditionalOnMissingBean(SkipPatternProvider.class)
	@EnableConfigurationProperties(SleuthWebProperties.class)
	protected static class SkipPatternProviderConfig {

		@Bean
		@ConditionalOnBean(ManagementServerProperties.class)
		public SkipPatternProvider skipPatternForManagementServerProperties(
				final ManagementServerProperties managementServerProperties,
				final SleuthWebProperties sleuthWebProperties) {
			return new SkipPatternProvider() {
				@Override
				public Pattern skipPattern() {
					return getPatternForManagementServerProperties(
							managementServerProperties,
							sleuthWebProperties);
				}
			};
		}

		/**
		 * Sets or appends {@link ManagementServerProperties#getContextPath()} to the skip
		 * pattern. If neither is available then sets the default one
		 */
		static Pattern getPatternForManagementServerProperties(
				ManagementServerProperties managementServerProperties,
				SleuthWebProperties sleuthWebProperties) {
			String skipPattern = sleuthWebProperties.getSkipPattern();
			if (StringUtils.hasText(skipPattern)
					&& StringUtils.hasText(managementServerProperties.getContextPath())) {
				return Pattern.compile(skipPattern + "|"
						+ managementServerProperties.getContextPath() + ".*");
			}
			else if (StringUtils.hasText(managementServerProperties.getContextPath())) {
				return Pattern
						.compile(managementServerProperties.getContextPath() + ".*");
			}
			return defaultSkipPattern(skipPattern);
		}

		@Bean
		@ConditionalOnMissingBean(ManagementServerProperties.class)
		public SkipPatternProvider defaultSkipPatternBeanIfManagementServerPropsArePresent(SleuthWebProperties sleuthWebProperties) {
			return defaultSkipPatternProvider(sleuthWebProperties.getSkipPattern());
		}
	}

	@Bean
	@ConditionalOnMissingClass("org.springframework.boot.actuate.autoconfigure.ManagementServerProperties")
	@ConditionalOnMissingBean(SkipPatternProvider.class)
	public SkipPatternProvider defaultSkipPatternBean(SleuthWebProperties sleuthWebProperties) {
		return defaultSkipPatternProvider(sleuthWebProperties.getSkipPattern());
	}

	private static SkipPatternProvider defaultSkipPatternProvider(
			final String skipPattern) {
		return new SkipPatternProvider() {
			@Override
			public Pattern skipPattern() {
				return defaultSkipPattern(skipPattern);
			}
		};
	}

	private static Pattern defaultSkipPattern(String skipPattern) {
		return StringUtils.hasText(skipPattern) ? Pattern.compile(skipPattern)
				: Pattern.compile(SleuthWebProperties.DEFAULT_SKIP_PATTERN);
	}

	interface SkipPatternProvider {
		Pattern skipPattern();
	}
}

TraceWebAutoConfiguration執行的條件有這些:

  1. spring.sleuth.web.enabled不爲false,不設置默認爲true
  2. spring application context是一個web application context
  3. 當存在Trace bean
  4. 在TraceHttpAutoConfiguration初始化以後才能觸發

內部靜態類TraceWebMvcAutoConfiguration是爲了import TraceWebMvcConfigurer的配置,它的條件是存在WebMvcConfigurerAdapter類,此類是spring mvc包中提供給用戶自定義攔截器等功能的抽象類。
下面咱們看下TraceWebMvcConfigurer:

@Configuration
class TraceWebMvcConfigurer extends WebMvcConfigurerAdapter {
	@Autowired BeanFactory beanFactory;

	@Bean
	public TraceHandlerInterceptor traceHandlerInterceptor(BeanFactory beanFactory) {
		return new TraceHandlerInterceptor(beanFactory);
	}

	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(this.beanFactory.getBean(TraceHandlerInterceptor.class));
	}
}

TraceWebMvcConfigurer定義了一個TraceHandlerInterceptor攔截器,而後重寫addInterceptors方法,將攔截器設置到了spring mvc生命週期中。後期會對TraceHandlerInterceptor攔截器進行分析。
接下來分析TraceWebAutoConfiguration生成的每一個bean。

traceWebAspect

@Aspect
public class TraceWebAspect {

	private static final Log log = org.apache.commons.logging.LogFactory
			.getLog(TraceWebAspect.class);

	private final Tracer tracer;
	private final SpanNamer spanNamer;
	private final TraceKeys traceKeys;

	public TraceWebAspect(Tracer tracer, SpanNamer spanNamer, TraceKeys traceKeys) {
		this.tracer = tracer;
		this.spanNamer = spanNamer;
		this.traceKeys = traceKeys;
	}

	@Pointcut("@within(org.springframework.web.bind.annotation.RestController)")
	private void anyRestControllerAnnotated() { }// NOSONAR

	@Pointcut("@within(org.springframework.stereotype.Controller)")
	private void anyControllerAnnotated() { } // NOSONAR

	@Pointcut("execution(public java.util.concurrent.Callable *(..))")
	private void anyPublicMethodReturningCallable() { } // NOSONAR

	@Pointcut("(anyRestControllerAnnotated() || anyControllerAnnotated()) && anyPublicMethodReturningCallable()")
	private void anyControllerOrRestControllerWithPublicAsyncMethod() { } // NOSONAR

	@Pointcut("execution(public org.springframework.web.context.request.async.WebAsyncTask *(..))")
	private void anyPublicMethodReturningWebAsyncTask() { } // NOSONAR

	@Pointcut("execution(public * org.springframework.web.servlet.HandlerExceptionResolver.resolveException(..)) && args(request, response, handler, ex)")
	private void anyHandlerExceptionResolver(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { } // NOSONAR

	@Pointcut("(anyRestControllerAnnotated() || anyControllerAnnotated()) && anyPublicMethodReturningWebAsyncTask()")
	private void anyControllerOrRestControllerWithPublicWebAsyncTaskMethod() { } // NOSONAR

	@Around("anyControllerOrRestControllerWithPublicAsyncMethod()")
	@SuppressWarnings("unchecked")
	public Object wrapWithCorrelationId(ProceedingJoinPoint pjp) throws Throwable {
		Callable<Object> callable = (Callable<Object>) pjp.proceed();
		if (this.tracer.isTracing()) {
			if (log.isDebugEnabled()) {
				log.debug("Wrapping callable with span [" + this.tracer.getCurrentSpan() + "]");
			}
			return new SpanContinuingTraceCallable<>(this.tracer, this.traceKeys, this.spanNamer, callable);
		}
		else {
			return callable;
		}
	}

	@Around("anyControllerOrRestControllerWithPublicWebAsyncTaskMethod()")
	public Object wrapWebAsyncTaskWithCorrelationId(ProceedingJoinPoint pjp) throws Throwable {
		final WebAsyncTask<?> webAsyncTask = (WebAsyncTask<?>) pjp.proceed();
		if (this.tracer.isTracing()) {
			try {
				if (log.isDebugEnabled()) {
					log.debug("Wrapping callable with span [" + this.tracer.getCurrentSpan()
							+ "]");
				}
				Field callableField = WebAsyncTask.class.getDeclaredField("callable");
				callableField.setAccessible(true);
				callableField.set(webAsyncTask, new SpanContinuingTraceCallable<>(this.tracer,
						this.traceKeys, this.spanNamer, webAsyncTask.getCallable()));
			} catch (NoSuchFieldException ex) {
				log.warn("Cannot wrap webAsyncTask's callable with TraceCallable", ex);
			}
		}
		return webAsyncTask;
	}

	@Around("anyHandlerExceptionResolver(request, response, handler, ex)")
	public Object markRequestForSpanClosing(ProceedingJoinPoint pjp,
			HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Throwable {
		Span currentSpan = this.tracer.getCurrentSpan();
		try {
			if (!currentSpan.tags().containsKey(Span.SPAN_ERROR_TAG_NAME)) {
				this.tracer.addTag(Span.SPAN_ERROR_TAG_NAME, ExceptionUtils.getExceptionMessage(ex));
			}
			return pjp.proceed();
		} finally {
			if (log.isDebugEnabled()) {
				log.debug("Marking span " + currentSpan + " for closure by Trace Filter");
			}
			request.setAttribute(TraceFilter.TRACE_CLOSE_SPAN_REQUEST_ATTR, true);
		}
	}

此bean對兩種狀況進行了aop攔截:

  1. 對RestController、Controller註解,而後這些條件組合進行Around處理。當在spring mvc的controller中有方法直接返回java.util.concurrent.Callable或者WebAsyncTask對象進行異步操做的時候是須要將trace的上下文設置到異步上下文中,方便後續trace的操做,因此須要對這些狀況進行aop,包裝trace信息,返回一個wrap對象。
  2. 對HandlerExceptionResolver.resolveException方法進行了攔截,針對異常作了一些標識處理。

traceSpringDataBeanPostProcessor

首先判斷是否存在org.springframework.data.rest.webmvc.support.DelegatingHandlerMapping,便是否引入了spring data rest相關依賴包。沒有的話則不會生成該bean。
該bean的主要做用是對Spring Data REST Controllers進行了包裝,生成TraceDelegatingHandlerMapping代理類,該類對被代理類進行了攔截器設置,攔截器爲前部分講到的TraceHandlerInterceptor。

traceFilter

trace攔截器,對每一個請求進行攔截,在spring mvc的攔截器以前觸發。他的主要做用是從request head中獲取trace信息,生成span,沒有trace信息則生成一個新的span。

traceWebFilter

將traceFilter註冊到servlet容器中。也就是用java config形式代替了在web.xml中配置filter。

spring sleuth的核心配置分析完後,下面分析本章最後的部分-ZipkinAutoConfiguration。

ZipkinAutoConfiguration

@Configuration
@EnableConfigurationProperties({ZipkinProperties.class, SamplerProperties.class})
@ConditionalOnProperty(value = "spring.zipkin.enabled", matchIfMissing = true)
@AutoConfigureBefore(TraceAutoConfiguration.class)
public class ZipkinAutoConfiguration {

	@Bean
	@ConditionalOnMissingBean
	public ZipkinSpanReporter reporter(SpanMetricReporter spanMetricReporter, ZipkinProperties zipkin,
			ZipkinRestTemplateCustomizer zipkinRestTemplateCustomizer) {
		RestTemplate restTemplate = new RestTemplate();
		zipkinRestTemplateCustomizer.customize(restTemplate);
		return new HttpZipkinSpanReporter(restTemplate, zipkin.getBaseUrl(), zipkin.getFlushInterval(),
				spanMetricReporter);
	}

	@Bean
	@ConditionalOnMissingBean
	public ZipkinRestTemplateCustomizer zipkinRestTemplateCustomizer(ZipkinProperties zipkinProperties) {
		return new DefaultZipkinRestTemplateCustomizer(zipkinProperties);
	}

	@Bean
	@ConditionalOnMissingBean
	public Sampler defaultTraceSampler(SamplerProperties config) {
		return new PercentageBasedSampler(config);
	}

	@Bean
	public SpanReporter zipkinSpanListener(ZipkinSpanReporter reporter, EndpointLocator endpointLocator,
			Environment environment, List<SpanAdjuster> spanAdjusters) {
		return new ZipkinSpanListener(reporter, endpointLocator, environment, spanAdjusters);
	}

	@Configuration
	@ConditionalOnMissingBean(EndpointLocator.class)
	@ConditionalOnProperty(value = "spring.zipkin.locator.discovery.enabled", havingValue = "false", matchIfMissing = true)
	protected static class DefaultEndpointLocatorConfiguration {

		@Autowired(required=false)
		private ServerProperties serverProperties;

		@Autowired
		private ZipkinProperties zipkinProperties;

		@Autowired(required=false)
		private InetUtils inetUtils;

		@Value("${spring.application.name:unknown}")
		private String appName;

		@Bean
		public EndpointLocator zipkinEndpointLocator() {
			return new ServerPropertiesEndpointLocator(this.serverProperties, this.appName,
					this.zipkinProperties, this.inetUtils);
		}

	}

	@Configuration
	@ConditionalOnClass(DiscoveryClient.class)
	@ConditionalOnMissingBean(EndpointLocator.class)
	@ConditionalOnProperty(value = "spring.zipkin.locator.discovery.enabled", havingValue = "true")
	protected static class DiscoveryClientEndpointLocatorConfiguration {

		@Autowired(required=false)
		private ServerProperties serverProperties;

		@Autowired
		private ZipkinProperties zipkinProperties;

		@Autowired(required=false)
		private InetUtils inetUtils;

		@Value("${spring.application.name:unknown}")
		private String appName;

		@Autowired(required=false)
		private DiscoveryClient client;

		@Bean
		public EndpointLocator zipkinEndpointLocator() {
			return new FallbackHavingEndpointLocator(discoveryClientEndpointLocator(),
					new ServerPropertiesEndpointLocator(this.serverProperties, this.appName,
							this.zipkinProperties, this.inetUtils));
		}

		private DiscoveryClientEndpointLocator discoveryClientEndpointLocator() {
			if (this.client!=null) {
				return new DiscoveryClientEndpointLocator(this.client, this.zipkinProperties);
			}
			return null;
		}

	}

}

ZipkinAutoConfiguration上的annotation就不一一說明,前部分已經涉及到了。下面直接分析生成的bean。

reporter

返回HttpZipkinSpanReporter類型bean,內部會初始化sender以及delegate。sender是以何種方式將zipkin span發送到zipkin server。delegate是一個委託類,內部建立一個有界隊列,異步將zipkin span發送到zipkin server。

zipkinRestTemplateCustomizer

建立reporter bean時須要依賴的sender。這裏zipkin使用restTemplate做爲sender提交span。

defaultTraceSampler

默認採樣器,以前在TraceAutoConfiguration中也聲明建立defaultTraceSampler,但因爲ZipkinAutoConfiguration上有這樣的註解:@AutoConfigureBefore(TraceAutoConfiguration.class),意思是在TraceAutoConfiguration以前執行,因此默認採樣器使用的是ZipkinAutoConfiguration中生成的採樣器即PercentageBasedSampler,它能夠設置百分比來進行採樣。

zipkinSpanListener

sleuth event監聽器,上報sleuth span,而後轉換成zipkin span,再經過zipkin reporter上報到zipkin server。

本章就到此結束了,其實還有hystrix、async相關模塊的配置沒講,本章只講了web相關的,後期有機會再講。

相關文章
相關標籤/搜索