版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
目录
摘要
Brave 2018年之前的版本基本已经废弃了,现在都是使用2019年最新的版本。博文使用的是目前最新的5.8.0版本。其基本原理就是使用Brave的拦截器来拦截RestTemplate的http请求,并发送给zipkin的Collector。对于现有的Sping boot 服务来说,修改不是太多。详细也可以参考:https://github.com/openzipkin/brave-webmvc-example
zipkin部署
zipkin 部署有多重方式,In-Memory方式 、MySql方式 、Elasticsearch方式 。这里使用最简单的In-Memory方式。最新的下载是在:http://central.maven.org/maven2/io/zipkin/java/zipkin-server/2.12.9/
注意:内存存储,zipkin重启后数据会丢失,建议测试环境使用,启动方式如下。
nohup java -jar zipkin-server-2.11.7-exec.jar &
POM文件修改
扫描二维码关注公众号,回复:
7571013 查看本文章
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!—添加基础POM ①->
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-bom</artifactId>
<version>5.8.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!—添加依赖包2->
<!-- Adds the MVC class and method names to server spans -->
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-spring-web</artifactId>
</dependency>
<!-- Adds the MVC class and method names to server spans -->
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-spring-webmvc</artifactId>
</dependency>
<!-- Instruments the underlying HttpClient requests that call the backend -->
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-httpclient</artifactId>
</dependency>
<!-- Integrates so you can use log patterns like %X{traceId}/%X{spanId} -->
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-context-slf4j</artifactId>
</dependency>
<!-- The below are needed to report traces to http://localhost:9411/api/v2/spans -->
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave</artifactId>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-sender-okhttp3</artifactId>
</dependency>
配置文件修改
spring:
application:
name: tlan
zipkin:
# zipkin服务端 这里使用的是单点 ①
base-url: http://127.0.0.1:9411/api/v2/spans
#zipkin启用开关 ②
turnOn: true
配置类添加
import java.util.ArrayList;
import java.util.List;
import javax.servlet.Filter;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import brave.Tracing;
import brave.context.slf4j.MDCScopeDecorator;
import brave.http.HttpTracing;
import brave.propagation.B3Propagation;
import brave.propagation.ExtraFieldPropagation;
import brave.propagation.ThreadLocalCurrentTraceContext;
import brave.servlet.TracingFilter;
import brave.spring.web.TracingClientHttpRequestInterceptor;
import brave.spring.webmvc.SpanCustomizingAsyncHandlerInterceptor;
import zipkin2.Span;
import zipkin2.reporter.AsyncReporter;
import zipkin2.reporter.Sender;
import zipkin2.reporter.okhttp3.OkHttpSender;
/**
* This adds tracing configuration to any web mvc controllers or rest template
* clients.
*/
@Configuration
@Import(SpanCustomizingAsyncHandlerInterceptor.class)
@AutoConfigureAfter(LoadBalancerAutoConfiguration.class) //①要考虑其他的拦截器,比如负载均衡的拦截器
public class TracingConfiguration extends WebMvcConfigurerAdapter {
/** Configuration for how to send spans to Zipkin */
@Value("${spring.zipkin.baseUrl:http://127.0.0.1:9411/api/v2/spans}")
private String baseUrl;
@Value("${spring.zipkin.turnOn:false}")
private boolean turnOn;
@Value("${spring.application.name}")
private String serviceName;
@Bean
Sender sender() {
return OkHttpSender.create(baseUrl);
}
/** Configuration for how to buffer spans into messages for Zipkin */
@Bean
AsyncReporter<Span> spanReporter() {
return AsyncReporter.create(sender());
}
/** Controls aspects of tracing such as the name that shows up in the UI */
@Bean
Tracing tracing() {
return Tracing.newBuilder().localServiceName(serviceName)
.propagationFactory(ExtraFieldPropagation.newFactory(B3Propagation.FACTORY, "user-name"))
.currentTraceContext(ThreadLocalCurrentTraceContext.newBuilder()
.addScopeDecorator(MDCScopeDecorator.create()).build())
.spanReporter(spanReporter()).build();
}
/**
* decides how to name and tag spans. By default they are named the same as the
* http method.
*/
@Bean
HttpTracing httpTracing(Tracing tracing) {
return HttpTracing.create(tracing);
}
/** Creates client spans for http requests */
// We are using a BPP as the Frontend supplies a RestTemplate bean prior to this
// configuration
@Bean
BeanPostProcessor connectionFactoryDecorator(final BeanFactory beanFactory) {
if (turnOn) {
return new BeanPostProcessor() {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (!(bean instanceof RestTemplate))
return bean;
RestTemplate restTemplate = (RestTemplate) bean;
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>(restTemplate.getInterceptors());
//② 如果之前添加了 loadBalancerInterceptor负载均衡拦截器或者其他的拦截器,这里只能在原来的基础上添加新的拦截器,属于Spring AOP设计。
//③不放第一个位置也行
interceptors.add(0, getTracingInterceptor());
restTemplate.setInterceptors(interceptors);
return bean;
}
// Lazy lookup so that the BPP doesn't end up needing to proxy anything.
ClientHttpRequestInterceptor getTracingInterceptor() {
return TracingClientHttpRequestInterceptor.create(beanFactory.getBean(HttpTracing.class));
}
};
} else {
return null;
}
}
/** Creates server spans for http requests */
@Bean
Filter tracingFilter(HttpTracing httpTracing) {
return TracingFilter.create(httpTracing);
}
@Autowired
SpanCustomizingAsyncHandlerInterceptor webMvcTracingCustomizer;
/** Decorates server spans with application-defined web tags */
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(webMvcTracingCustomizer);
}
}
注意的地方
凡是需要注意的地方都加了标注。