調用鏈系列二、Zipkin 和 Brave 實現(springmvc、RestTemplate)服務調用跟蹤


Brave介紹

1、Brave簡介

Brave 是用來裝備 Java 程序的類庫,提供了面向標准Servlet、Spring MVC、Http Client、JAX RS、Jersey、Resteasy 和 MySQL 等接口的裝備能力,可以通過編寫簡單的配置和代碼,讓基於這些框架構建的應用可以向 Zipkin 報告數據。同時 Brave 也提供了非常簡單且標准化的接口,在以上封裝無法滿足要求的時候可以方便擴展與定制。

雖然Brave提供了默認的實現,結合項目實際情況,基本上是需要定制才能滿足要求的,本文針對默認實現就不再啰嗦,直接針對定制進行講解。

由於項目中用到SpringMvc,HttpClient,Jprotobuf-Rpc-Socket,本文主要介紹針對SpringMvc,HttpClient,Jprotobuf-Rpc-Socket的擴展與定制。

2、服務調用常用的兩種方式

1、服務以Http方式提供Rest接口,服務與服務之間通過HttpClient互相調用,對外以Http方式提供Rest接口,這里Rest以SpringMvc為例。

2、服務以jprotobufrpcsocket方式提供Rpc接口,服務與服務之間通過RPC互相調用,對外以Http方式提供Rest接口,這里Rest以SpringMvc為例,RPC以jprotobufrpcsocket為例。

3、Brave環境准備

1、Maven引入

<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">
  <modelVersion>4.0.0</modelVersion>
  
  <groupId>io.zipkin.brave</groupId>
  <artifactId>brave-webmvc-example</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>
 
  <name>brave-webmvc-examplea</name>
  <description>Example using Brave to trace RPCs from Spring Web MVC</description>
  <url>https://github.com/openzipkin/brave-webmvc-example</url>
 
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <spring.version>4.3.3.RELEASE</spring.version>
    <jetty.version>8.1.20.v20160902</jetty.version>
    <brave.version>3.16.0</brave.version>
    <zipkin-reporter.version>0.6.9</zipkin-reporter.version>
  </properties>
  
  <dependencies>
  <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.10</version>
      <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>io.zipkin.brave</groupId>
        <artifactId>brave-core-spring</artifactId>
        <version>${brave.version}</version>
    </dependency>
    <dependency>
      <groupId>io.zipkin.reporter</groupId>
      <artifactId>zipkin-sender-okhttp3</artifactId>
      <version>${zipkin-reporter.version}</version>
    </dependency>
    <dependency>
      <groupId>io.zipkin.reporter</groupId>
      <artifactId>zipkin-sender-libthrift</artifactId>
      <version>${zipkin-reporter.version}</version>
    </dependency>
    <dependency>
      <groupId>io.zipkin.reporter</groupId>
      <artifactId>zipkin-sender-kafka08</artifactId>
      <version>${zipkin-reporter.version}</version>
    </dependency>
    <dependency>
        <groupId>io.zipkin.brave</groupId>
        <artifactId>brave-spring-web-servlet-interceptor</artifactId>
        <version>${brave.version}</version>
    </dependency>
    <dependency>
      <groupId>io.zipkin.brave</groupId>
      <artifactId>brave-spring-resttemplate-interceptors</artifactId>
      <version>${brave.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
       <groupId>org.eclipse.jetty</groupId>
       <artifactId>jetty-server</artifactId>
       <version>${jetty.version}</version>
       <scope>test</scope>
    </dependency>
    <dependency>
       <groupId>org.eclipse.jetty</groupId>
       <artifactId>jetty-webapp</artifactId>
       <version>${jetty.version}</version>
       <scope>test</scope>
    </dependency>
        <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.21</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jcl-over-slf4j</artifactId>
        <version>1.7.21</version>
    </dependency>
  </dependencies>
  <build>
       <plugins>
            <plugin>
                <inherited>true</inherited>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <optimize>true</optimize>
                    <debug>true</debug>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>2.19.1</version>
                <executions>
                     <execution>
                        <id>integration-test</id>
                        <goals>
                           <goal>integration-test</goal>
                        </goals>
                       </execution>
                     <execution>
                         <id>verify</id>
                         <goals>
                           <goal>verify</goal>
                         </goals>
                     </execution>
                </executions>
           </plugin>
           <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.0.0</version>
                <configuration>
                     <webResources>
                        <resource>
                           <directory>${basedir}/src/main/webapp</directory>
                           <filtering>true</filtering>
                           <includes>
                              <include>**/index.html</include>
                           </includes>
                        </resource>
                        <resource>
                           <directory>${basedir}/src/main/webapp/WEB-INF</directory>
                           <filtering>true</filtering>
                           <targetPath>WEB-INF</targetPath>
                           <includes>
                              <include>**/web.xml</include>
                           </includes>
                        </resource>
                     </webResources>
                     <packagingExcludes>WEB-INF/lib/servlet-api-*.jar</packagingExcludes>
                  </configuration>
           </plugin>
    </plugins>
  </build>
</project>
View Code

2、配置埋點(servlet攔截器)

WebTracingConfiguration.java

package com.example.demo.common;
import com.github.kristofa.brave.Brave;
import com.github.kristofa.brave.http.DefaultSpanNameProvider;
import com.github.kristofa.brave.http.SpanNameProvider;
import com.github.kristofa.brave.spring.BraveClientHttpRequestInterceptor;
import com.github.kristofa.brave.spring.ServletHandlerInterceptor;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
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 zipkin.Span;
import zipkin.reporter.AsyncReporter;
import zipkin.reporter.Reporter;
import zipkin.reporter.Sender;
import zipkin.reporter.okhttp3.OkHttpSender;


/**
 * This adds tracing configuration to any web mvc controllers or rest template clients. This should
 * be configured last.
 */
@Configuration
// import as the interceptors are annotation with javax.inject and not automatically wired
@Import({BraveClientHttpRequestInterceptor.class, ServletHandlerInterceptor.class})
public class WebTracingConfiguration extends WebMvcConfigurerAdapter {


    /** 發送器配置 */
    @Bean Sender sender() {
        return OkHttpSender.create("http://47.52.199.51:9411/api/v1/spans");
        //return LibthriftSender.create("127.0.0.1");
        // return KafkaSender.create("127.0.0.1:9092");
    }


    /** 用什么方式顯示span信息 */
    @Bean Reporter<Span> reporter() {
        //取消注釋,日志打印span信息
        //return new LoggingReporter(); // 打印日志本地,通過日志收集到ES
        return AsyncReporter.builder(sender()).build();
    }

    @Bean Brave brave() {
        return new Brave.Builder("brave-webmvc-zipkin").reporter(reporter()).build();
    }
    // span命名提供者,默認為http方法.
    @Bean SpanNameProvider spanNameProvider() {
        return new DefaultSpanNameProvider();
    }


    @Autowired
    private ServletHandlerInterceptor serverInterceptor;


    @Autowired
    private BraveClientHttpRequestInterceptor clientInterceptor;


    @Autowired
    private RestTemplate restTemplate;

    @Bean
    RestTemplate template() {
        return new RestTemplate();
    }


    // 添加rest template攔截器
    @PostConstruct
    public void init() {
        List<ClientHttpRequestInterceptor> interceptors = new ArrayList<ClientHttpRequestInterceptor>(restTemplate.getInterceptors());
        interceptors.add(clientInterceptor);
        restTemplate.setInterceptors(interceptors);
    }

    // 添加Severlet攔截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(serverInterceptor);
    }
}

2、ZipkinController.java

package com.example.demo.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class ZipkinController {
    @Autowired RestTemplate template;

    @GetMapping("/zipkin")
    public String service() throws Exception {
        return template.getForObject("http://192.168.1.100:8080/service0", String.class);
    }
}

 4、運行

1、訪問:http://192.168.1.100:8084/zipkin

service0~service2部分請看:調用鏈系列一、Zipkin架構介紹、搭建、Springboot集承、Zipkin UI詳解

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM