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