增加 zipkin 示例

This commit is contained in:
YunaiV
2020-01-07 00:32:35 +08:00
parent 609cf51d1e
commit cdef8e8780
10 changed files with 281 additions and 1 deletions

View File

@@ -76,7 +76,7 @@
## 链路追踪
* [《芋道 Spring Boot 链路追踪 SkyWalking 入门》](http://www.iocoder.cn/Spring-Boot/SkyWalking/?github) 对应 [lab-37](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-37) 。
* [《芋道 Spring Boot 链路追踪 SkyWalking 入门》](http://www.iocoder.cn/Spring-Boot/SkyWalking/?github) 对应 [lab-39](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-39) 。
* [《芋道 Spring Boot 链路追踪 Zipkin 入门》](http://www.iocoder.cn/Spring-Boot/Zipkin/?github) 对应 [lab-38](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-38) 。
* [《芋道 Spring Boot 链路追踪 Pinpoint 入门》](http://www.iocoder.cn/Spring-Boot/Pinpoint/?github) 对应 [lab-39](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-38) 。

View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>lab-40-demo</artifactId>
<dependencies>
<!-- 实现对 SpringMVC 的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</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>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-bom</artifactId>
<version>5.9.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>

View File

@@ -0,0 +1,13 @@
package cn.iocoder.springboot.lab40.zipkindemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

View File

@@ -0,0 +1,15 @@
package cn.iocoder.springboot.lab40.zipkindemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application2 {
public static void main(String[] args) {
System.setProperty("spring.application.name", "demo-application-02");
System.setProperty("server.port", "8079");
SpringApplication.run(Application2.class, args);
}
}

View File

@@ -0,0 +1,25 @@
package cn.iocoder.springboot.lab40.zipkindemo.config;
import brave.spring.webmvc.SpanCustomizingAsyncHandlerInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@Import(SpanCustomizingAsyncHandlerInterceptor.class)
public class SpringMvcConfiguration implements WebMvcConfigurer {
@Autowired
public SpanCustomizingAsyncHandlerInterceptor webMvcTracingCustomizer;
/**
* Decorates server spans with application-defined web tags
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(webMvcTracingCustomizer);
}
}

View File

@@ -0,0 +1,103 @@
package cn.iocoder.springboot.lab40.zipkindemo.config;
import brave.CurrentSpanCustomizer;
import brave.SpanCustomizer;
import brave.Tracing;
import brave.http.HttpTracing;
import brave.httpclient.TracingHttpClientBuilder;
import brave.propagation.B3Propagation;
import brave.propagation.ExtraFieldPropagation;
import brave.servlet.TracingFilter;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.client.RestTemplateCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import zipkin2.Span;
import zipkin2.reporter.AsyncReporter;
import zipkin2.reporter.Sender;
import zipkin2.reporter.okhttp3.OkHttpSender;
import javax.servlet.Filter;
@Configuration
public class ZipkinConfiguration {
/**
* Configuration for how to send spans to Zipkin
*/
@Bean
public Sender sender() {
return OkHttpSender.create("http://127.0.0.1:9411/api/v2/spans");
}
/**
* Configuration for how to buffer spans into messages for Zipkin
*/
@Bean
public AsyncReporter<Span> spanReporter() {
return AsyncReporter.create(sender());
}
/**
* Controls aspects of tracing such as the service name that shows up in the UI
*/
@Bean
public Tracing tracing(@Value("${spring.application.name}") String serviceName) {
return Tracing.newBuilder()
.localServiceName(serviceName)
.propagationFactory(ExtraFieldPropagation.newFactory(B3Propagation.FACTORY, "user-name"))
// .currentTraceContext(ThreadLocalCurrentTraceContext.newBuilder()
// .addScopeDecorator(MDCScopeDecorator.create()) // puts trace IDs into logs
// .build()
// )
.spanReporter(spanReporter()).build();
}
/**
* Allows someone to add tags to a span if a trace is in progress
*/
@Bean
public SpanCustomizer spanCustomizer(Tracing tracing) {
return CurrentSpanCustomizer.create(tracing);
}
// ==================== HTTP 相关 ====================
/**
* Decides how to name and tag spans. By default they are named the same as the http method
*/
@Bean
public HttpTracing httpTracing(Tracing tracing) {
return HttpTracing.create(tracing);
}
/**
* Creates server spans for http requests
*/
@Bean
public Filter tracingFilter(HttpTracing httpTracing) {
return TracingFilter.create(httpTracing);
}
// ==================== SpringMVC 相关 ====================
// @see SpringMvcConfiguration 类上的,@Import(SpanCustomizingAsyncHandlerInterceptor.class)
// ==================== HttpClient 相关 ====================
@Bean
public RestTemplateCustomizer useTracedHttpClient(HttpTracing httpTracing) {
// 创建 CloseableHttpClient 对象,内置 HttpTracing 进行 HTTP 链路追踪。
final CloseableHttpClient httpClient = TracingHttpClientBuilder.create(httpTracing).build();
// 创建 RestTemplateCustomizer 对象
return new RestTemplateCustomizer() {
@Override
public void customize(RestTemplate restTemplate) {
restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient));
}
};
}
}

View File

@@ -0,0 +1,32 @@
package cn.iocoder.springboot.lab40.zipkindemo.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
@RequestMapping("/demo")
public class DemoController {
private final RestTemplate restTemplate;
DemoController(@Autowired RestTemplateBuilder restTemplateBuilder) {
this.restTemplate = restTemplateBuilder.build();
}
@GetMapping("/echo")
public String echo() {
return "echo";
}
@GetMapping("/http")
public String http() {
// restTemplate.getForObject("https://www.baidu.com", String.class);
restTemplate.getForObject("http://127.0.0.1:8079/demo/echo", String.class);
return "echo";
}
}

View File

@@ -0,0 +1,3 @@
spring:
application:
name: demo-application

19
lab-40/pom.xml Normal file
View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>labs-parent</artifactId>
<groupId>cn.iocoder.springboot.labs</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>lab-40</artifactId>
<packaging>pom</packaging>
<modules>
<module>lab-40-demo</module>
</modules>
</project>

View File

@@ -48,6 +48,7 @@
<module>lab-37</module>
<module>lab-38</module>
<module>lab-39</module>
<module>lab-40</module>
</modules>