sleuth 原理

sleuth 原理

为什么 sleuth 处理线程,线程池之类的操作,和平时无异,却依旧能记录 traceId?

ExecutorBeanPostProcessor

主要 是这个后置处理器对常用 的线程池,线程进行了了包装

public class ExecutorBeanPostProcessor implements BeanPostProcessor {

	private static final Log log = LogFactory.getLog(ExecutorBeanPostProcessor.class);

	private final BeanFactory beanFactory;

	private SleuthAsyncProperties sleuthAsyncProperties;

	public ExecutorBeanPostProcessor(BeanFactory beanFactory) {
		this.beanFactory = beanFactory;
	}

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if (!ExecutorInstrumentor.isApplicableForInstrumentation(bean)) {
			return bean;
		}
		return new ExecutorInstrumentor(() -> sleuthAsyncProperties().getIgnoredBeans(), this.beanFactory)
				.instrument(bean, beanName);
	}

	private SleuthAsyncProperties sleuthAsyncProperties() {
		if (this.sleuthAsyncProperties == null) {
			this.sleuthAsyncProperties = this.beanFactory.getBean(SleuthAsyncProperties.class);
		}
		return this.sleuthAsyncProperties;
	}

}

ExecutorInstrumentor

这个类主要 是包装线程池

public class ExecutorInstrumentor {

	private static final Log log = LogFactory.getLog(ExecutorInstrumentor.class);

	private final Supplier<List<String>> ignoredBeans;

	private final BeanFactory beanFactory;

	public ExecutorInstrumentor(Supplier<List<String>> ignoredBeans, BeanFactory beanFactory) {
		this.ignoredBeans = ignoredBeans;
		this.beanFactory = beanFactory;
	}

	/**
	 * @param bean bean to instrument
	 * @return {@code true} if bean is applicable for instrumentation
	 */
	public static boolean isApplicableForInstrumentation(Object bean) {
		return bean instanceof Executor && !(bean instanceof LazyTraceThreadPoolTaskExecutor
				|| bean instanceof TraceableScheduledExecutorService || bean instanceof TraceableExecutorService
				|| bean instanceof LazyTraceAsyncTaskExecutor || bean instanceof LazyTraceExecutor);
	}

	/**
	 * Wraps an {@link Executor} bean in its trace representation.
	 * @param bean a bean (might be of {@link Executor} type
	 * @param beanName name of the bean
	 * @return wrapped bean or just bean if not {@link Executor} or already instrumented
	 */
	public Object instrument(Object bean, String beanName) {
		if (!isApplicableForInstrumentation(bean)) {
			log.info("Bean is already instrumented or is not applicable for instrumentation " + beanName);
			return bean;
		}
		if (bean instanceof ThreadPoolTaskExecutor) {
			if (isProxyNeeded(beanName)) {
				return wrapThreadPoolTaskExecutor(bean, beanName);
			}
			else {
				log.info("Not instrumenting bean " + beanName);
			}
		}
		else if (bean instanceof ScheduledExecutorService) {
			if (isProxyNeeded(beanName)) {
				return wrapScheduledExecutorService(bean, beanName);
			}
			else {
				log.info("Not instrumenting bean " + beanName);
			}
		}
		else if (bean instanceof ExecutorService) {
			if (isProxyNeeded(beanName)) {
				return wrapExecutorService(bean, beanName);
			}
			else {
				log.info("Not instrumenting bean " + beanName);
			}
		}
		else if (bean instanceof AsyncTaskExecutor) {
			if (isProxyNeeded(beanName)) {
				return wrapAsyncTaskExecutor(bean, beanName);
			}
			else {
				log.info("Not instrumenting bean " + beanName);
			}
		}
		else if (bean instanceof Executor) {
			return wrapExecutor(bean, beanName);
		}
		return bean;
	}
}

你可能感兴趣的:(spring,boot,java,mybatis,数据库)