brave本身没有对AsyncHttpClient提供类似于brave-okhttp的ClientRequestInterceptor和ClientResponseInterceptor,所以需要我们定制,而ServerRequestInterceptor和ServerResponseInterceptor是在BraveServletFilter部分直接指定就好了(这在任何client技术下都可以复用)。
实际上,ClientRequestInterceptor和ClientResponseInterceptor也是我们的定制点。
一、代码
基本参考第二十七章 springboot + zipkin(brave-okhttp实现)
1、service1
1.1、pom.xml
1 <!-- zipkin brave --> 2 <dependency> 3 <groupId>io.zipkin.brave</groupId> 4 <artifactId>brave-core</artifactId> 5 <version>3.9.0</version> 6 </dependency> 7 <dependency> 8 <groupId>io.zipkin.brave</groupId> 9 <artifactId>brave-spancollector-http</artifactId> 10 <version>3.9.0</version> 11 </dependency> 12 <dependency> 13 <groupId>io.zipkin.brave</groupId> 14 <artifactId>brave-web-servlet-filter</artifactId> 15 <version>3.9.0</version> 16 </dependency> 17 <!-- async-http-client --> 18 <dependency> 19 <groupId>com.ning</groupId> 20 <artifactId>async-http-client</artifactId> 21 <version>1.9.31</version> 22 </dependency>
1.2、ZipkinConfig
1 package com.xxx.service1.zipkin.brave.async; 2 3 import org.springframework.context.annotation.Bean; 4 import org.springframework.context.annotation.Configuration; 5 6 import com.github.kristofa.brave.Brave; 7 import com.github.kristofa.brave.EmptySpanCollectorMetricsHandler; 8 import com.github.kristofa.brave.Sampler; 9 import com.github.kristofa.brave.SpanCollector; 10 import com.github.kristofa.brave.http.DefaultSpanNameProvider; 11 import com.github.kristofa.brave.http.HttpSpanCollector; 12 import com.github.kristofa.brave.servlet.BraveServletFilter; 13 import com.ning.http.client.AsyncHttpClient; 14 15 @Configuration 16 public class ZipkinConfig { 17 @Bean 18 public SpanCollector spanCollector() { 19 HttpSpanCollector.Config spanConfig = HttpSpanCollector.Config.builder() 20 .compressionEnabled(false)//默认false,span在transport之前是否会被gzipped。 21 .connectTimeout(5000)//5s,默认10s 22 .flushInterval(1)//1s 23 .readTimeout(6000)//5s,默认60s 24 .build(); 25 return HttpSpanCollector.create("http://localhost:9411", 26 spanConfig, 27 new EmptySpanCollectorMetricsHandler()); 28 } 29 30 @Bean 31 public Brave brave(SpanCollector spanCollector) { 32 Brave.Builder builder = new Brave.Builder("asyn1 - service1 - 1");//指定serviceName 33 builder.spanCollector(spanCollector); 34 builder.traceSampler(Sampler.create(1));//采集率 35 return builder.build(); 36 } 37 38 @Bean 39 public BraveServletFilter braveServletFilter(Brave brave) { 40 /** 41 * 设置sr、ss拦截器 42 */ 43 return new BraveServletFilter(brave.serverRequestInterceptor(), 44 brave.serverResponseInterceptor(), 45 new DefaultSpanNameProvider()); 46 } 47 48 @Bean 49 public AsyncHttpClient asyncHttpClient(){ 50 return new AsyncHttpClient(); 51 } 52 }
说明:指定了serviceName:"asyn1 - service1 - 1"
1.3、ZipkinAsyncController
1 package com.xxx.service1.zipkin.brave.async; 2 3 import java.net.URI; 4 import java.util.concurrent.Future; 5 6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.web.bind.annotation.RequestMapping; 8 import org.springframework.web.bind.annotation.RequestMethod; 9 import org.springframework.web.bind.annotation.RestController; 10 11 import com.github.kristofa.brave.Brave; 12 import com.github.kristofa.brave.http.DefaultSpanNameProvider; 13 import com.github.kristofa.brave.http.HttpClientRequest; 14 import com.github.kristofa.brave.http.HttpClientRequestAdapter; 15 import com.github.kristofa.brave.http.HttpClientResponseAdapter; 16 import com.github.kristofa.brave.http.HttpResponse; 17 import com.ning.http.client.AsyncHttpClient; 18 import com.ning.http.client.Request; 19 import com.ning.http.client.RequestBuilder; 20 import com.ning.http.client.Response; 21 22 import io.swagger.annotations.Api; 23 import io.swagger.annotations.ApiOperation; 24 25 @Api("zipkin brave async api") 26 @RestController 27 @RequestMapping("/zipkin/async/service1") 28 public class ZipkinAsyncController { 29 30 @Autowired 31 private AsyncHttpClient asyncHttpClient; 32 @Autowired 33 private Brave brave; 34 35 @ApiOperation("trace第一步") 36 @RequestMapping(value = "/test1", method = RequestMethod.GET) 37 public String myboot() { 38 39 try { 40 RequestBuilder builder = new RequestBuilder(); 41 String url = "http://localhost:8032/zipkin/async/service2/test2"; 42 builder.setUrl(url); 43 Request request = builder.build(); 44 45 clientRequestInterceptor(request); 46 Future<Response> response = asyncHttpClient.executeRequest(request); 47 clientResponseInterceptor(response.get()); 48 49 return response.get().getResponseBody(); 50 } catch (Exception e) { 51 e.printStackTrace(); 52 return ""; 53 } 54 } 55 56 private void clientRequestInterceptor(Request request) { 57 brave.clientRequestInterceptor().handle(new HttpClientRequestAdapter(new HttpClientRequest() { 58 59 @Override 60 public URI getUri() { 61 return URI.create(request.getUrl()); 62 } 63 64 @Override 65 public String getHttpMethod() { 66 return request.getMethod(); 67 } 68 69 @Override 70 public void addHeader(String headerKey, String headerValue) { 71 request.getHeaders().add(headerKey, headerValue); 72 } 73 }, new DefaultSpanNameProvider())); 74 } 75 76 private void clientResponseInterceptor(Response response) { 77 brave.clientResponseInterceptor().handle(new HttpClientResponseAdapter(new HttpResponse() { 78 public int getHttpStatusCode() { 79 return response.getStatusCode(); 80 } 81 })); 82 } 83 84 }
说明:
- clientRequestInterceptor(com.ning.http.client.Request request)
- 其实就是在做cs
- clientResponseInterceptor(com.ning.http.client.Response response)
- 其实就是在做cr
2、service2
2.1、pom.xml
1 <!-- zipkin brave --> 2 <dependency> 3 <groupId>io.zipkin.brave</groupId> 4 <artifactId>brave-core</artifactId> 5 <version>3.9.0</version> 6 </dependency> 7 <dependency> 8 <groupId>io.zipkin.brave</groupId> 9 <artifactId>brave-spancollector-http</artifactId> 10 <version>3.9.0</version> 11 </dependency> 12 <dependency> 13 <groupId>io.zipkin.brave</groupId> 14 <artifactId>brave-web-servlet-filter</artifactId> 15 <version>3.9.0</version> 16 </dependency> 17 <!-- async-http-client --> 18 <dependency> 19 <groupId>com.ning</groupId> 20 <artifactId>async-http-client</artifactId> 21 <version>1.9.31</version> 22 </dependency>
2.2、ZipkinConfig
1 package com.xxx.service1.zipkin.brave.async; 2 3 import org.springframework.context.annotation.Bean; 4 import org.springframework.context.annotation.Configuration; 5 6 import com.github.kristofa.brave.Brave; 7 import com.github.kristofa.brave.EmptySpanCollectorMetricsHandler; 8 import com.github.kristofa.brave.Sampler; 9 import com.github.kristofa.brave.SpanCollector; 10 import com.github.kristofa.brave.http.DefaultSpanNameProvider; 11 import com.github.kristofa.brave.http.HttpSpanCollector; 12 import com.github.kristofa.brave.servlet.BraveServletFilter; 13 import com.ning.http.client.AsyncHttpClient; 14 15 @Configuration 16 public class ZipkinConfig { 17 @Bean 18 public SpanCollector spanCollector() { 19 HttpSpanCollector.Config spanConfig = HttpSpanCollector.Config.builder() 20 .compressionEnabled(false)//默认false,span在transport之前是否会被gzipped。 21 .connectTimeout(5000)//5s,默认10s 22 .flushInterval(1)//1s 23 .readTimeout(6000)//5s,默认60s 24 .build(); 25 return HttpSpanCollector.create("http://localhost:9411", 26 spanConfig, 27 new EmptySpanCollectorMetricsHandler()); 28 } 29 30 @Bean 31 public Brave brave(SpanCollector spanCollector) { 32 Brave.Builder builder = new Brave.Builder("asyn2 - service2 - 2");//指定serviceName 33 builder.spanCollector(spanCollector); 34 builder.traceSampler(Sampler.create(1));//采集率 35 return builder.build(); 36 } 37 38 @Bean 39 public BraveServletFilter braveServletFilter(Brave brave) { 40 /** 41 * 设置sr、ss拦截器 42 */ 43 return new BraveServletFilter(brave.serverRequestInterceptor(), 44 brave.serverResponseInterceptor(), 45 new DefaultSpanNameProvider()); 46 } 47 48 @Bean 49 public AsyncHttpClient asyncHttpClient(){ 50 return new AsyncHttpClient(); 51 } 52 }
说明:指定了serviceName:"asyn2 - service2 - 2"
2.3、ZipkinAsyncController
1 package com.xxx.service2.zipkin.brave.async; 2 3 import java.net.URI; 4 import java.util.concurrent.Future; 5 6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.web.bind.annotation.RequestMapping; 8 import org.springframework.web.bind.annotation.RequestMethod; 9 import org.springframework.web.bind.annotation.RestController; 10 11 import com.github.kristofa.brave.Brave; 12 import com.github.kristofa.brave.http.DefaultSpanNameProvider; 13 import com.github.kristofa.brave.http.HttpClientRequest; 14 import com.github.kristofa.brave.http.HttpClientRequestAdapter; 15 import com.github.kristofa.brave.http.HttpClientResponseAdapter; 16 import com.github.kristofa.brave.http.HttpResponse; 17 import com.ning.http.client.AsyncHttpClient; 18 import com.ning.http.client.Request; 19 import com.ning.http.client.RequestBuilder; 20 import com.ning.http.client.Response; 21 22 import io.swagger.annotations.Api; 23 import io.swagger.annotations.ApiOperation; 24 25 @Api("zipkin brave async api") 26 @RestController 27 @RequestMapping("/zipkin/async/service2") 28 public class ZipkinAsyncController { 29 30 @Autowired 31 private AsyncHttpClient asyncHttpClient; 32 @Autowired 33 private Brave brave; 34 35 @ApiOperation("trace第2步") 36 @RequestMapping(value = "/test2", method = RequestMethod.GET) 37 public String myboot2() { 38 39 try { 40 /*****************************serivce3*******************************/ 41 RequestBuilder builder3 = new RequestBuilder(); 42 String url3 = "http://localhost:8033/zipkin/async/service3/test3"; 43 builder3.setUrl(url3); 44 Request request3 = builder3.build(); 45 46 clientRequestInterceptor(request3); 47 Future<Response> response3 = asyncHttpClient.executeRequest(request3); 48 clientResponseInterceptor(response3.get()); 49 50 /*****************************serivce4*******************************/ 51 RequestBuilder builder4 = new RequestBuilder(); 52 String url4 = "http://localhost:8034/zipkin/async/service4/test4"; 53 builder4.setUrl(url4); 54 Request request4 = builder4.build(); 55 56 clientRequestInterceptor(request4); 57 Future<Response> response4 = asyncHttpClient.executeRequest(request4); 58 clientResponseInterceptor(response4.get()); 59 60 return response3.get().getResponseBody() + "=====" + response4.get().getResponseBody(); 61 } catch (Exception e) { 62 e.printStackTrace(); 63 return ""; 64 } 65 } 66 67 private void clientRequestInterceptor(Request request) { 68 brave.clientRequestInterceptor().handle(new HttpClientRequestAdapter(new HttpClientRequest() { 69 70 @Override 71 public URI getUri() { 72 return URI.create(request.getUrl()); 73 } 74 75 @Override 76 public String getHttpMethod() { 77 return request.getMethod(); 78 } 79 80 @Override 81 public void addHeader(String headerKey, String headerValue) { 82 request.getHeaders().add(headerKey, headerValue); 83 } 84 }, new DefaultSpanNameProvider())); 85 } 86 87 private void clientResponseInterceptor(Response response) { 88 brave.clientResponseInterceptor().handle(new HttpClientResponseAdapter(new HttpResponse() { 89 public int getHttpStatusCode() { 90 return response.getStatusCode(); 91 } 92 })); 93 } 94 95 }
3、service3
3.1、pom.xml
1 <!-- zipkin brave --> 2 <dependency> 3 <groupId>io.zipkin.brave</groupId> 4 <artifactId>brave-core</artifactId> 5 <version>3.9.0</version> 6 </dependency> 7 <dependency> 8 <groupId>io.zipkin.brave</groupId> 9 <artifactId>brave-spancollector-http</artifactId> 10 <version>3.9.0</version> 11 </dependency> 12 <dependency> 13 <groupId>io.zipkin.brave</groupId> 14 <artifactId>brave-web-servlet-filter</artifactId> 15 <version>3.9.0</version> 16 </dependency>
3.2、ZipkinConfig
1 package com.xxx.service3.zipkin.brave.async; 2 3 import org.springframework.context.annotation.Bean; 4 import org.springframework.context.annotation.Configuration; 5 6 import com.github.kristofa.brave.Brave; 7 import com.github.kristofa.brave.EmptySpanCollectorMetricsHandler; 8 import com.github.kristofa.brave.Sampler; 9 import com.github.kristofa.brave.SpanCollector; 10 import com.github.kristofa.brave.http.DefaultSpanNameProvider; 11 import com.github.kristofa.brave.http.HttpSpanCollector; 12 import com.github.kristofa.brave.servlet.BraveServletFilter; 13 14 @Configuration 15 public class ZipkinConfig { 16 @Bean 17 public SpanCollector spanCollector() { 18 HttpSpanCollector.Config spanConfig = HttpSpanCollector.Config.builder() 19 .compressionEnabled(false)//默认false,span在transport之前是否会被gzipped。 20 .connectTimeout(5000)//5s,默认10s 21 .flushInterval(1)//1s 22 .readTimeout(6000)//5s,默认60s 23 .build(); 24 return HttpSpanCollector.create("http://localhost:9411", 25 spanConfig, 26 new EmptySpanCollectorMetricsHandler()); 27 } 28 29 @Bean 30 public Brave brave(SpanCollector spanCollector) { 31 Brave.Builder builder = new Brave.Builder("asyn3 - service3 - 3");//指定serviceName 32 builder.spanCollector(spanCollector); 33 builder.traceSampler(Sampler.create(1));//采集率 34 return builder.build(); 35 } 36 37 @Bean 38 public BraveServletFilter braveServletFilter(Brave brave) { 39 /** 40 * 设置sr、ss拦截器 41 */ 42 return new BraveServletFilter(brave.serverRequestInterceptor(), 43 brave.serverResponseInterceptor(), 44 new DefaultSpanNameProvider()); 45 } 46 }
说明:指定了serviceName:"asyn3 - service3 - 3"
3.3、ZipkinAsyncController
1 package com.xxx.service3.zipkin.brave.async; 2 3 import org.springframework.web.bind.annotation.RequestMapping; 4 import org.springframework.web.bind.annotation.RequestMethod; 5 import org.springframework.web.bind.annotation.RestController; 6 7 import io.swagger.annotations.Api; 8 import io.swagger.annotations.ApiOperation; 9 10 @Api("zipkin brave async api") 11 @RestController 12 @RequestMapping("/zipkin/async/service3") 13 public class ZipkinAsyncController { 14 15 @ApiOperation("trace第3步") 16 @RequestMapping(value = "/test3", method = RequestMethod.GET) 17 public String myboot3() { 18 19 try { 20 return "async - service3"; 21 } catch (Exception e) { 22 e.printStackTrace(); 23 return ""; 24 } 25 } 26 27 }
4、service4
4.1、pom.xml
1 <!-- zipkin brave --> 2 <dependency> 3 <groupId>io.zipkin.brave</groupId> 4 <artifactId>brave-core</artifactId> 5 <version>3.9.0</version> 6 </dependency> 7 <dependency> 8 <groupId>io.zipkin.brave</groupId> 9 <artifactId>brave-spancollector-http</artifactId> 10 <version>3.9.0</version> 11 </dependency> 12 <dependency> 13 <groupId>io.zipkin.brave</groupId> 14 <artifactId>brave-web-servlet-filter</artifactId> 15 <version>3.9.0</version> 16 </dependency>
4.2、ZipkinConfig
1 package com.xxx.service4.zipkin.brave.async; 2 3 import org.springframework.context.annotation.Bean; 4 import org.springframework.context.annotation.Configuration; 5 6 import com.github.kristofa.brave.Brave; 7 import com.github.kristofa.brave.EmptySpanCollectorMetricsHandler; 8 import com.github.kristofa.brave.Sampler; 9 import com.github.kristofa.brave.SpanCollector; 10 import com.github.kristofa.brave.http.DefaultSpanNameProvider; 11 import com.github.kristofa.brave.http.HttpSpanCollector; 12 import com.github.kristofa.brave.servlet.BraveServletFilter; 13 14 @Configuration 15 public class ZipkinConfig { 16 @Bean 17 public SpanCollector spanCollector() { 18 HttpSpanCollector.Config spanConfig = HttpSpanCollector.Config.builder() 19 .compressionEnabled(false)//默认false,span在transport之前是否会被gzipped。 20 .connectTimeout(5000)//5s,默认10s 21 .flushInterval(1)//1s 22 .readTimeout(6000)//5s,默认60s 23 .build(); 24 return HttpSpanCollector.create("http://localhost:9411", 25 spanConfig, 26 new EmptySpanCollectorMetricsHandler()); 27 } 28 29 @Bean 30 public Brave brave(SpanCollector spanCollector) { 31 Brave.Builder builder = new Brave.Builder("asyn4 - service4 - 4");//指定serviceName 32 builder.spanCollector(spanCollector); 33 builder.traceSampler(Sampler.create(1));//采集率 34 return builder.build(); 35 } 36 37 @Bean 38 public BraveServletFilter braveServletFilter(Brave brave) { 39 /** 40 * 设置sr、ss拦截器 41 */ 42 return new BraveServletFilter(brave.serverRequestInterceptor(), 43 brave.serverResponseInterceptor(), 44 new DefaultSpanNameProvider()); 45 } 46 47 }
说明:指定了serviceName:"asyn4 - service4 - 4"
4.3、ZipkinAsyncController
1 package com.xxx.service4.zipkin.brave.async; 2 3 import org.springframework.web.bind.annotation.RequestMapping; 4 import org.springframework.web.bind.annotation.RequestMethod; 5 import org.springframework.web.bind.annotation.RestController; 6 7 import io.swagger.annotations.Api; 8 import io.swagger.annotations.ApiOperation; 9 10 @Api("zipkin brave async api") 11 @RestController 12 @RequestMapping("/zipkin/async/service4") 13 public class ZipkinAsyncController { 14 15 @ApiOperation("trace第4步") 16 @RequestMapping(value = "/test4", method = RequestMethod.GET) 17 public String myboot3() { 18 19 try { 20 return "async - service4"; 21 } catch (Exception e) { 22 e.printStackTrace(); 23 return ""; 24 } 25 } 26 27 }
二、测试结果
1、依赖关系图:
2、span时间消耗图
3、详情图
点击第4个span,查看详情: