spring boot +brave-5.8.0+zipkin 实现分布式链路监控

目录

摘要

zipkin部署

POM文件修改

配置文件修改

配置类添加


摘要

Brave  2018年之前的版本基本已经废弃了,现在都是使用2019年最新的版本。博文使用的是目前最新的5.8.0版本。其基本原理就是使用Brave的拦截器来拦截RestTemplatehttp请求,并发送给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文件修改

   


        
           
               org.springframework.cloud
               spring-cloud-dependencies
               Finchley.SR3
               pom
               import
           
             
           
               io.zipkin.brave
               brave-bom
               5.8.0
               pom
               import
           
        
    


        
        
           io.zipkin.brave
           brave-instrumentation-spring-web
        

           
        
           io.zipkin.brave
           brave-instrumentation-spring-webmvc
        

        
        
           io.zipkin.brave
           brave-instrumentation-httpclient
        

        
        
           io.zipkin.brave
           brave-context-slf4j
        

        
        
           io.zipkin.brave
           brave
        

        
           io.zipkin.reporter2
           zipkin-sender-okhttp3
        

 

配置文件修改

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 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 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);

    }

}

 

 

注意的地方

凡是需要注意的地方都加了标注。

 

你可能感兴趣的:(微服务)