首页 > 代码库 > 第二十八章 springboot + zipkin(brave定制-AsyncHttpClient)
第二十八章 springboot + zipkin(brave定制-AsyncHttpClient)
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 @Configuration16 public class ZipkinConfig {17 @Bean18 public SpanCollector spanCollector() {19 HttpSpanCollector.Config spanConfig = HttpSpanCollector.Config.builder()20 .compressionEnabled(false)//默认false,span在transport之前是否会被gzipped。21 .connectTimeout(5000)//5s,默认10s22 .flushInterval(1)//1s23 .readTimeout(6000)//5s,默认60s24 .build();25 return HttpSpanCollector.create("http://localhost:9411", 26 spanConfig,27 new EmptySpanCollectorMetricsHandler());28 }29 30 @Bean31 public Brave brave(SpanCollector spanCollector) {32 Brave.Builder builder = new Brave.Builder("asyn1 - service1 - 1");//指定serviceName33 builder.spanCollector(spanCollector);34 builder.traceSampler(Sampler.create(1));//采集率35 return builder.build();36 }37 38 @Bean39 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 @Bean49 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 @RestController27 @RequestMapping("/zipkin/async/service1")28 public class ZipkinAsyncController {29 30 @Autowired31 private AsyncHttpClient asyncHttpClient;32 @Autowired33 private Brave brave;34 35 @ApiOperation("trace第一步")36 @RequestMapping(value = "http://www.mamicode.com/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 @Override60 public URI getUri() {61 return URI.create(request.getUrl());62 }63 64 @Override65 public String getHttpMethod() {66 return request.getMethod();67 }68 69 @Override70 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 @Configuration16 public class ZipkinConfig {17 @Bean18 public SpanCollector spanCollector() {19 HttpSpanCollector.Config spanConfig = HttpSpanCollector.Config.builder()20 .compressionEnabled(false)//默认false,span在transport之前是否会被gzipped。21 .connectTimeout(5000)//5s,默认10s22 .flushInterval(1)//1s23 .readTimeout(6000)//5s,默认60s24 .build();25 return HttpSpanCollector.create("http://localhost:9411", 26 spanConfig,27 new EmptySpanCollectorMetricsHandler());28 }29 30 @Bean31 public Brave brave(SpanCollector spanCollector) {32 Brave.Builder builder = new Brave.Builder("asyn2 - service2 - 2");//指定serviceName33 builder.spanCollector(spanCollector);34 builder.traceSampler(Sampler.create(1));//采集率35 return builder.build();36 }37 38 @Bean39 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 @Bean49 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 @RestController27 @RequestMapping("/zipkin/async/service2")28 public class ZipkinAsyncController {29 30 @Autowired31 private AsyncHttpClient asyncHttpClient;32 @Autowired33 private Brave brave;34 35 @ApiOperation("trace第2步")36 @RequestMapping(value = "http://www.mamicode.com/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 @Override71 public URI getUri() {72 return URI.create(request.getUrl());73 }74 75 @Override76 public String getHttpMethod() {77 return request.getMethod();78 }79 80 @Override81 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 @Configuration15 public class ZipkinConfig {16 @Bean17 public SpanCollector spanCollector() {18 HttpSpanCollector.Config spanConfig = HttpSpanCollector.Config.builder()19 .compressionEnabled(false)//默认false,span在transport之前是否会被gzipped。20 .connectTimeout(5000)//5s,默认10s21 .flushInterval(1)//1s22 .readTimeout(6000)//5s,默认60s23 .build();24 return HttpSpanCollector.create("http://localhost:9411", 25 spanConfig,26 new EmptySpanCollectorMetricsHandler());27 }28 29 @Bean30 public Brave brave(SpanCollector spanCollector) {31 Brave.Builder builder = new Brave.Builder("asyn3 - service3 - 3");//指定serviceName32 builder.spanCollector(spanCollector);33 builder.traceSampler(Sampler.create(1));//采集率34 return builder.build();35 }36 37 @Bean38 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 @RestController12 @RequestMapping("/zipkin/async/service3")13 public class ZipkinAsyncController {14 15 @ApiOperation("trace第3步")16 @RequestMapping(value = "http://www.mamicode.com/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 @Configuration15 public class ZipkinConfig {16 @Bean17 public SpanCollector spanCollector() {18 HttpSpanCollector.Config spanConfig = HttpSpanCollector.Config.builder()19 .compressionEnabled(false)//默认false,span在transport之前是否会被gzipped。20 .connectTimeout(5000)//5s,默认10s21 .flushInterval(1)//1s22 .readTimeout(6000)//5s,默认60s23 .build();24 return HttpSpanCollector.create("http://localhost:9411", 25 spanConfig,26 new EmptySpanCollectorMetricsHandler());27 }28 29 @Bean30 public Brave brave(SpanCollector spanCollector) {31 Brave.Builder builder = new Brave.Builder("asyn4 - service4 - 4");//指定serviceName32 builder.spanCollector(spanCollector);33 builder.traceSampler(Sampler.create(1));//采集率34 return builder.build();35 }36 37 @Bean38 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 @RestController12 @RequestMapping("/zipkin/async/service4")13 public class ZipkinAsyncController {14 15 @ApiOperation("trace第4步")16 @RequestMapping(value = "http://www.mamicode.com/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,查看详情:
第二十八章 springboot + zipkin(brave定制-AsyncHttpClient)