Zipkin和Brave实现http服务调用的跟踪

使用Zipkin和Brave实现http服务调用的跟踪,Brave 是用来装备Java程序的类库,提供了面向标准Servlet、Spring MVC、Http Client、JAX RS、Jersey、Resteasy 和 MySQL 等接口的装备能力,可以通过编写简单的配置和代码,让基于这些框架构建的应用可以向 Zipkin 报告数据。同时 Brave 也提供了非常简单且标准化的接口,在以上封装无法满足要求的时候可以方便扩展与定制。

提供四个工程,分别对应四个服务分别是:zipkin1,zipkin2,zipkin3,zipkin4;zipkin1通过httpclient调用zipkin2,然后zipkin2通过httpclient调用zipkin3和zipkin4,形成一个调用链;四个服务都是基于spring-boot来实现,对应的端口分别是8081,8082,8083,8084;

1.公共maven依赖库

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>io.zipkin.brave</groupId>
        <artifactId>brave-core</artifactId>
        <version>3.9.0</version>
    </dependency>
    <dependency>
        <groupId>io.zipkin.brave</groupId>
        <artifactId>brave-spancollector-http</artifactId>
        <version>3.9.0</version>
    </dependency>
    <dependency>
        <groupId>io.zipkin.brave</groupId>
        <artifactId>brave-web-servlet-filter</artifactId>
        <version>3.9.0</version>
    </dependency>
    <dependency>
        <groupId>io.zipkin.brave</groupId>
        <artifactId>brave-apache-http-interceptors</artifactId>
        <version>3.9.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
    </dependency>
</dependencies>

2.核心类ZipkinBean提供需要使用的Bean

import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
import com.github.kristofa.brave.Brave;
import com.github.kristofa.brave.Brave.Builder;
import com.github.kristofa.brave.EmptySpanCollectorMetricsHandler;
import com.github.kristofa.brave.Sampler;
import com.github.kristofa.brave.SpanCollector;
import com.github.kristofa.brave.http.DefaultSpanNameProvider;
import com.github.kristofa.brave.http.HttpSpanCollector;
import com.github.kristofa.brave.http.HttpSpanCollector.Config;
import com.github.kristofa.brave.httpclient.BraveHttpRequestInterceptor;
import com.github.kristofa.brave.httpclient.BraveHttpResponseInterceptor;
import com.github.kristofa.brave.servlet.BraveServletFilter;
 
@Configuration
public class ZipkinBean {
 
    /**
     * 配置收集器
     * 
     * @return
     */
    @Bean
    public SpanCollector spanCollector() {
        Config config = HttpSpanCollector.Config.builder().compressionEnabled(false).connectTimeout(5000)
                .flushInterval(1).readTimeout(6000).build();
        return HttpSpanCollector.create("http://192.168.237.128:9411", config, new EmptySpanCollectorMetricsHandler());
    }
 
    /**
     * Brave各工具类的封装
     * 
     * @param spanCollector
     * @return
     */
    @Bean
    public Brave brave(SpanCollector spanCollector) {
        Builder builder = new Builder("service1");// 指定serviceName
        builder.spanCollector(spanCollector);
        builder.traceSampler(Sampler.create(1));// 采集率
        return builder.build();
    }
 
    /**
     * 拦截器,需要serverRequestInterceptor,serverResponseInterceptor 分别完成sr和ss操作
     * 
     * @param brave
     * @return
     */
    @Bean
    public BraveServletFilter braveServletFilter(Brave brave) {
        return new BraveServletFilter(brave.serverRequestInterceptor(), brave.serverResponseInterceptor(),
                new DefaultSpanNameProvider());
    }
 
    /**
     * httpClient客户端,需要clientRequestInterceptor,clientResponseInterceptor分别完成cs和cr操作
     * 
     * @param brave
     * @return
     */
    @Bean
    public CloseableHttpClient httpClient(Brave brave) {
        CloseableHttpClient httpclient = HttpClients.custom()
                .addInterceptorFirst(new BraveHttpRequestInterceptor(brave.clientRequestInterceptor(),
                        new DefaultSpanNameProvider()))
                .addInterceptorFirst(new BraveHttpResponseInterceptor(brave.clientResponseInterceptor())).build();
        return httpclient;
    }
}

3.核心类ZipkinController对外接口

@RestController
public class ZipkinController {
 
    @Autowired
    private CloseableHttpClient httpClient;
 
    @GetMapping("/service1")
    public String service() throws Exception {
        Thread.sleep(100);
        HttpGet get = new HttpGet("http://localhost:8082/service2");
        CloseableHttpResponse response = httpClient.execute(get);
        return EntityUtils.toString(response.getEntity(), "utf-8");
    }
}

分别启动四个服务,然后浏览器访问:http://localhost:8081/service1,正常调用结果返回:

service3 service4

可以观察zipkin web ui,查看服务的调用链:

posted on 2018-07-18 23:38  duanxz  阅读(4138)  评论(1编辑  收藏  举报