使用Zipkin 和 Brave 实现http(springmvc)服务调用跟踪(一)
来源:互联网 发布:php 大端 编辑:程序博客网 时间:2024/06/05 16:45
Zipkin 是一款开源的分布式实时数据追踪系统(Distributed Tracking System),基于 Google Dapper 的论文设计而来,由 Twitter 公司开发贡献。其主要功能是聚集来自各个异构系统的实时监控数据,用来追踪微服务架构下的系统延时问题。
Brave 是用来装备 Java 程序的类库,提供了面向 Standard Servlet、Spring MVC、Http Client、JAX RS、Jersey、Resteasy 和 MySQL 等接口的装备能力,可以通过编写简单的配置和代码,让基于这些框架构建的应用可以向 Zipkin 报告数据。同时 Brave 也提供了非常简单且标准化的接口,在以上封装无法满足要求的时候可以方便扩展与定制(下篇会讲)。
有关zipkin与Brave的详细介绍:http://www.tuicool.com/articles/f2qAZnZ
客户端发起请求到接收到服务端回应,先后经过四个阶段:客户端/消费者发起请求(cs)、服务端/生产者接收到请求(sr)、服务端/生产者发送应答(ss)和客户端/消费者接收到应答(cr)。Brave为Spring提供的Servlet拦截器(ServletHandlerInterceptor)及Rest(BraveClientHttpRequestInterceptor)模板的拦截器,向zipkin报告监控数据,其中,BraveClientHttpRequestInterceptor负责cs与cr的处理,ServletHandlerInterceptor负责sr与ss的处理。
好,开始实验这两个拦截器的使用,目标是发布两个服务a和b,在a中调用b服务,记录调用的跟踪信息。
git项目地址:https://github.com/blacklau/brave-webmvc-example (forked from openzipkin/brave-webmvc-example ,请忽略README.md说明)
1、pom.xml
<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、Brave的初始化及添加拦截器
package brave.webmvc;import com.github.kristofa.brave.Brave;import com.github.kristofa.brave.LoggingReporter;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.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://127.0.0.1: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(); return AsyncReporter.builder(sender()).build(); } @Bean Brave brave() { return new Brave.Builder("brave-webmvc-example").reporter(reporter()).build(); } // span命名提供者,默认为http方法. @Bean SpanNameProvider spanNameProvider() { return new DefaultSpanNameProvider(); } @Autowired private ServletHandlerInterceptor serverInterceptor; @Autowired private BraveClientHttpRequestInterceptor clientInterceptor; @Autowired private RestTemplate 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); }}
3、springmvc的controller,发布a和b两个服务
package brave.webmvc;import java.util.Random;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;import org.springframework.web.servlet.config.annotation.EnableWebMvc;@RestController@EnableWebMvc@Configurationpublic class ExampleController { @Bean RestTemplate template() { return new RestTemplate(); } @Autowired RestTemplate template; @RequestMapping("/a") public String a() throws InterruptedException { Random random = new Random(); Thread.sleep(random.nextInt(1000)); return template.getForObject("http://localhost:8080/brave-webmvc-example/b", String.class); } @RequestMapping("/b") public String b() throws InterruptedException { Random random = new Random(); Thread.sleep(random.nextInt(1000)); return "b"; }}
4、web.xml配置
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"><web-app><display-name>brave webmvc example</display-name><servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextClass</param-name> <param-value> org.springframework.web.context.support.AnnotationConfigWebApplicationContext </param-value> </init-param> <init-param> <param-name>contextConfigLocation</param-name> <!-- Loads the application configuration and resource. Tracing configuration is optional and goes last. --> <param-value>brave.webmvc.ExampleControllerbrave.webmvc.WebTracingConfiguration</param-value> </init-param> <load-on-startup>1</load-on-startup></servlet><servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/*</url-pattern></servlet-mapping></web-app>
5、下载zipkin并运行
下载地址: https://search.maven.org/remote_content?g=io.zipkin.java&a=zipkin-server&v=LATEST&c=exec
运行: java -jar zipkin.jar
6、git上下载项目,maven打war包(打包时,请跳过测试,否则报错)部署到tomcat或在开发环境中运行
访问a服务: http://localhost:8080/brave-webmvc-example/a
打开:http://localhost:9411,查看调用链跟踪信息及耗时
发现Brave提供的拦截器使用的Span的名称是默认的http的请求方法,好像没多大意义,且没有记录请求参数,若调用链中出现bug,不方便bug重现与问题排查,下一篇讲使用Brave的扩展与定制,重写span名称的获取与添加请求参数到跟踪信息中
- 使用Zipkin 和 Brave 实现http(springmvc)服务调用跟踪(一)
- 使用Zipkin 和 Brave 实现http(springmvc)服务调用跟踪(二)
- 使用Zipkin和Brave 实现dubbo服务调用跟踪
- zipkin 和 brave 使用
- Java分布式跟踪系统Zipkin(五):Brave源码分析-Brave和SpringMVC整合
- 使用 Zipkin 和 Brave 实现分布式系统追踪(基础篇
- 使用 Zipkin 和 Brave 实现分布式系统追踪
- Java分布式跟踪系统Zipkin(六):Brave源码分析-Brave和SpringBoot整合
- 使用 Zipkin 和 Brave 实现分布式系统追踪(基础篇)
- Java分布式跟踪系统Zipkin(二):Brave源码分析-Tracer和Span
- dubbo+zipkin的服务跟踪
- 分布式跟踪系统(一):Zipkin的背景和设计
- 分布式跟踪系统(一):Zipkin的背景和设计
- 分布式跟踪系统(一):Zipkin的背景和设计
- 分布式跟踪系统(一):Zipkin的背景和设计
- 分布式跟踪系统(一):Zipkin的背景和设计
- 分布式跟踪系统(一):Zipkin的背景和设计
- 使用Spring Sleuth和Zipkin跟踪微服务
- spring、springmvc和mybaites在maven整合
- 外部中断计数器
- 用Python绘制七段数码管
- Android 视频播放器SurfaceView+Mediaplayer
- 最简单的基于FFmpeg的推流器(以推送RTMP为例)
- 使用Zipkin 和 Brave 实现http(springmvc)服务调用跟踪(一)
- Ubuntu14.04 双显卡问题的显卡切换问题
- Hadoop集群启动常见异常
- Android单选多选控件使用
- 明明的随机数
- 我的安全之路——Web安全篇
- Linux下gcc编译器生成和使用静态库和动态库
- Android源码分析工具及方法
- 用HTML+PHP写一个留言板来进行XSS测试&学习 第一篇(GET反射型)