使用Zipkin 和 Brave 实现http(springmvc)服务调用跟踪(一)

简介:

使用Zipkin 和 Brave 实现http(springmvc)服务调用跟踪(一)

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

[html] view plain copy

  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2.   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  3.   <modelVersion>4.0.0</modelVersion>
  4.   <groupId>io.zipkin.brave</groupId>
  5.   <artifactId>brave-webmvc-example</artifactId>
  6.   <version>1.0-SNAPSHOT</version>
  7.   <packaging>war</packaging>
  8.   <name>brave-webmvc-examplea</name>
  9.   <description>Example using Brave to trace RPCs from Spring Web MVC</description>
  10.   <url>https://github.com/openzipkin/brave-webmvc-example</url>
  11.   <properties>
  12.     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  13.     <spring.version>4.3.3.RELEASE</spring.version>
  14.     <jetty.version>8.1.20.v20160902</jetty.version>
  15.     <brave.version>3.16.0</brave.version>
  16.     <zipkin-reporter.version>0.6.9</zipkin-reporter.version>
  17.   </properties>
  18.   <dependencies>
  19.   <dependency>
  20.       <groupId>junit</groupId>
  21.       <artifactId>junit</artifactId>
  22.       <version>4.10</version>
  23.       <scope>test</scope>
  24.     </dependency>
  25.     <dependency>
  26.         <groupId>io.zipkin.brave</groupId>
  27.         <artifactId>brave-core-spring</artifactId>
  28.         <version>${brave.version}</version>
  29.     </dependency>
  30.     <dependency>
  31.       <groupId>io.zipkin.reporter</groupId>
  32.       <artifactId>zipkin-sender-okhttp3</artifactId>
  33.       <version>${zipkin-reporter.version}</version>
  34.     </dependency>
  35.     <dependency>
  36.       <groupId>io.zipkin.reporter</groupId>
  37.       <artifactId>zipkin-sender-libthrift</artifactId>
  38.       <version>${zipkin-reporter.version}</version>
  39.     </dependency>
  40.     <dependency>
  41.       <groupId>io.zipkin.reporter</groupId>
  42.       <artifactId>zipkin-sender-kafka08</artifactId>
  43.       <version>${zipkin-reporter.version}</version>
  44.     </dependency>
  45.     <dependency>
  46.         <groupId>io.zipkin.brave</groupId>
  47.         <artifactId>brave-spring-web-servlet-interceptor</artifactId>
  48.         <version>${brave.version}</version>
  49.     </dependency>
  50.     <dependency>
  51.       <groupId>io.zipkin.brave</groupId>
  52.       <artifactId>brave-spring-resttemplate-interceptors</artifactId>
  53.       <version>${brave.version}</version>
  54.     </dependency>
  55.     <dependency>
  56.         <groupId>org.springframework</groupId>
  57.         <artifactId>spring-core</artifactId>
  58.         <version>${spring.version}</version>
  59.     </dependency>
  60.     <dependency>
  61.         <groupId>org.springframework</groupId>
  62.         <artifactId>spring-context</artifactId>
  63.         <version>${spring.version}</version>
  64.     </dependency>
  65.     <dependency>
  66.         <groupId>org.springframework</groupId>
  67.         <artifactId>spring-beans</artifactId>
  68.         <version>${spring.version}</version>
  69.     </dependency>
  70.     <dependency>
  71.         <groupId>org.springframework</groupId>
  72.         <artifactId>spring-web</artifactId>
  73.         <version>${spring.version}</version>
  74.     </dependency>
  75.     <dependency>
  76.         <groupId>org.springframework</groupId>
  77.         <artifactId>spring-webmvc</artifactId>
  78.         <version>${spring.version}</version>
  79.     </dependency>
  80.     <dependency>
  81.        <groupId>org.eclipse.jetty</groupId>
  82.        <artifactId>jetty-server</artifactId>
  83.        <version>${jetty.version}</version>
  84.        <scope>test</scope>
  85.     </dependency>
  86.     <dependency>
  87.        <groupId>org.eclipse.jetty</groupId>
  88.        <artifactId>jetty-webapp</artifactId>
  89.        <version>${jetty.version}</version>
  90.        <scope>test</scope>
  91.     </dependency>
  92.         <dependency>
  93.         <groupId>log4j</groupId>
  94.         <artifactId>log4j</artifactId>
  95.         <version>1.2.17</version>
  96.     </dependency>
  97.     <dependency>
  98.         <groupId>org.slf4j</groupId>
  99.         <artifactId>slf4j-log4j12</artifactId>
  100.         <version>1.7.21</version>
  101.     </dependency>
  102.     <dependency>
  103.         <groupId>org.slf4j</groupId>
  104.         <artifactId>jcl-over-slf4j</artifactId>
  105.         <version>1.7.21</version>
  106.     </dependency>
  107.   </dependencies>
  108.   <build>
  109.      <plugins>
  110.             <plugin>
  111.                 <inherited>true</inherited>
  112.                 <groupId>org.apache.maven.plugins</groupId>
  113.                 <artifactId>maven-compiler-plugin</artifactId>
  114.                 <version>2.5.1</version>
  115.                 <configuration>
  116.                     <source>1.6</source>
  117.                     <target>1.6</target>
  118.                     <optimize>true</optimize>
  119.                     <debug>true</debug>
  120.                 </configuration>
  121.             </plugin>
  122.             <plugin>
  123.                 <groupId>org.apache.maven.plugins</groupId>
  124.                 <artifactId>maven-failsafe-plugin</artifactId>
  125.                 <version>2.19.1</version>
  126.                 <executions>
  127.                      <execution>
  128.                         <id>integration-test</id>
  129.                         <goals>
  130.                            <goal>integration-test</goal>
  131.                         </goals>
  132.                      </execution>
  133.                      <execution>
  134.                          <id>verify</id>
  135.                          <goals>
  136.                            <goal>verify</goal>
  137.                          </goals>
  138.                      </execution>
  139.                 </executions>
  140.            </plugin>
  141.            <plugin>
  142.                 <groupId>org.apache.maven.plugins</groupId>
  143.                 <artifactId>maven-war-plugin</artifactId>
  144.                 <version>3.0.0</version>
  145.                 <configuration>
  146.                      <webResources>
  147.                         <resource>
  148.                            <directory>${basedir}/src/main/webapp</directory>
  149.                            <filtering>true</filtering>
  150.                            <includes>
  151.                               <include>**/index.html</include>
  152.                            </includes>
  153.                         </resource>
  154.                         <resource>
  155.                            <directory>${basedir}/src/main/webapp/WEB-INF</directory>
  156.                            <filtering>true</filtering>
  157.                            <targetPath>WEB-INF</targetPath>
  158.                            <includes>
  159.                               <include>**/web.xml</include>
  160.                            </includes>
  161.                         </resource>
  162.                      </webResources>
  163.                      <packagingExcludes>WEB-INF/lib/servlet-api-*.jar</packagingExcludes>
  164.                   </configuration>
  165.            </plugin>
  166.     </plugins>
  167.   </build>
  168. </project>

 

2、Brave的初始化及添加拦截器

[java] view plain copy

  1. <span style="font-size:18px;">package brave.webmvc;
  2. import com.github.kristofa.brave.Brave;
  3. import com.github.kristofa.brave.LoggingReporter;
  4. import com.github.kristofa.brave.http.DefaultSpanNameProvider;
  5. import com.github.kristofa.brave.http.SpanNameProvider;
  6. import com.github.kristofa.brave.spring.BraveClientHttpRequestInterceptor;
  7. import com.github.kristofa.brave.spring.ServletHandlerInterceptor;
  8. import java.util.ArrayList;
  9. import java.util.List;
  10. import javax.annotation.PostConstruct;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.context.annotation.Bean;
  13. import org.springframework.context.annotation.Configuration;
  14. import org.springframework.context.annotation.Import;
  15. import org.springframework.http.client.ClientHttpRequestInterceptor;
  16. import org.springframework.web.client.RestTemplate;
  17. import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
  18. import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
  19. import zipkin.Span;
  20. import zipkin.reporter.Reporter;
  21. import zipkin.reporter.Sender;
  22. import zipkin.reporter.okhttp3.OkHttpSender;
  23. /**
  24.  * This adds tracing configuration to any web mvc controllers or rest template clients. This should
  25.  * be configured last.
  26.  */
  27. @Configuration
  28. // import as the interceptors are annotation with javax.inject and not automatically wired
  29. @Import({BraveClientHttpRequestInterceptor.class, ServletHandlerInterceptor.class})
  30. public class WebTracingConfiguration extends WebMvcConfigurerAdapter {
  31.   /** 发送器配置 */
  32.   @Bean Sender sender() {
  33.     return OkHttpSender.create("http://127.0.0.1:9411/api/v1/spans");
  34.     //return LibthriftSender.create("127.0.0.1");
  35.     // return KafkaSender.create("127.0.0.1:9092");
  36.   }
  37.   /** 用什么方式显示span信息 */
  38.   @Bean Reporter<Span> reporter() {
  39. //取消注释,日志打印span信息
  40. //return new LoggingReporter(); 
  41.     return AsyncReporter.builder(sender()).build();
  42.   }
  43.   @Bean Brave brave() {
  44.     return new Brave.Builder("brave-webmvc-example").reporter(reporter()).build();
  45.   }
  46.   // span命名提供者,默认为http方法.
  47.   @Bean SpanNameProvider spanNameProvider() {
  48.     return new DefaultSpanNameProvider();
  49.   }
  50.   @Autowired
  51.   private ServletHandlerInterceptor serverInterceptor;
  52.   @Autowired
  53.   private BraveClientHttpRequestInterceptor clientInterceptor;
  54.   @Autowired
  55.   private RestTemplate restTemplate;
  56.   // 添加rest template拦截器
  57.   @PostConstruct
  58.   public void init() {
  59.     List<ClientHttpRequestInterceptor> interceptors =
  60.         new ArrayList<ClientHttpRequestInterceptor>(restTemplate.getInterceptors());
  61.     interceptors.add(clientInterceptor);
  62.     restTemplate.setInterceptors(interceptors);
  63.   }
  64.   // 添加Severlet拦截器
  65.   @Override
  66.   public void addInterceptors(InterceptorRegistry registry) {
  67.     registry.addInterceptor(serverInterceptor);
  68.   }
  69. }</span>

 

3、springmvc的controller,发布a和b两个服务

[java] view plain copy

  1. <span style="font-size:18px;">package brave.webmvc;
  2. import java.util.Random;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.Configuration;
  6. import org.springframework.web.bind.annotation.RequestMapping;
  7. import org.springframework.web.bind.annotation.RestController;
  8. import org.springframework.web.client.RestTemplate;
  9. import org.springframework.web.servlet.config.annotation.EnableWebMvc;
  10. @RestController
  11. @EnableWebMvc
  12. @Configuration
  13. public class ExampleController {
  14.   @Bean RestTemplate template() {
  15.     return new RestTemplate();
  16.   }
  17.   @Autowired RestTemplate template;
  18.   @RequestMapping("/a")
  19.   public String a() throws InterruptedException {
  20.     Random random = new Random();
  21.     Thread.sleep(random.nextInt(1000));
  22.     return template.getForObject("http://localhost:8080/brave-webmvc-example/b", String.class);
  23.   }
  24.   @RequestMapping("/b")
  25.   public String b() throws InterruptedException {
  26.     Random random = new Random();
  27.     Thread.sleep(random.nextInt(1000));
  28.     return "b";
  29.   }
  30. }</span>

 

4、web.xml配置

[html] view plain copy

  1. <span style="font-size:18px;"><?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
  3. <web-app>
  4. <display-name>brave webmvc example</display-name>
  5. <servlet>
  6.  <servlet-name>dispatcher</servlet-name>
  7.  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  8.  <init-param>
  9.  <param-name>contextClass</param-name>
  10.  <param-value>
  11.  org.springframework.web.context.support.AnnotationConfigWebApplicationContext
  12.  </param-value>
  13.  </init-param>
  14.  <init-param>
  15.  <param-name>contextConfigLocation</param-name>
  16.  <!--  Loads the application configuration and resource. Tracing configuration is optional and goes last. -->
  17.  <param-value>
  18. brave.webmvc.ExampleController
  19. brave.webmvc.WebTracingConfiguration
  20. </param-value>
  21.  </init-param>
  22.  <load-on-startup>1</load-on-startup>
  23. </servlet>
  24. <servlet-mapping>
  25.  <servlet-name>dispatcher</servlet-name>
  26.  <url-pattern>/*</url-pattern>
  27. </servlet-mapping>
  28. </web-app>
  29. </span>

 

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名称的获取与添加请求参数到跟踪信息中

原文地址http://www.bieryun.com/1919.html

相关文章
|
Web App开发 前端开发
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
总结和计划总是让人喜悦或镇痛,一方面以前一段时间没有荒废,能给现在的行动以信心,另一方面看到一年的时间并不能完成很多事情,需要抓紧时间。
617 0
|
Web App开发 监控 前端开发
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
系统的升级涉及各个架构组件,细节很多。常年累月的修修补补使老系统积累了很多问题。 系统升级则意味着需要repair之前埋下的雷,那为何还要升级,可以考虑以下几个方面 成熟老系统常见问题: 1. 缺乏文档(这应该是大小公司都存在的问题。
624 0
|
Web App开发 监控 前端开发
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
已发现2个内存错误,应用名称(kernel:),日志内容(hangzhou-jishuan-DDS0248 kernel: sbridge: HANDLING MCE MEMORY ERROR hangzhou-jis...
851 0
|
Web App开发 前端开发 Java
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
Changing Hive Dynamic Partition Limits Symptoms: Hive enforces limits on the number of dynamic partitions that it creates.
1026 0
|
Web App开发 前端开发
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
一个典型的星型模式包括一个大型的事实表和一组逻辑上围绕这个事实表的维度表。  事实表是星型模型的核心,事实表由主键和度量数据两部分组成。
542 0
|
机器学习/深度学习 Web App开发 前端开发
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
输入python,进入python命令行 import tensorflow as tf tf.__version__ 查询tensorflow安装路径为: tf.
721 0
|
Web App开发 前端开发 Linux
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
一般来说,Linux的虚拟内存会根据系统负载自动调整。内存页(page)swap到磁盘会显著的影响Kafka的性能,并且Kafka重度使用page cache,如果VM系统swap到磁盘,那说明没有足够的内存来分配page cache。
666 0
下一篇
无影云桌面