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>
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詳解