【弄nèng - SpringCloud】应用篇 —— 整合Zipkin【Finchley版】

Spring Cloud:分布式服务跟踪,整合Zipkin【Finchley版】,实测跟Dalston版没啥区别。
参考地址传送门1
参考地址传送门2
参考地址传送门3
参考地址传送门4

注意:本文是http传送数据方式,生产不建议使用,建议使用消息队列传送数据,es存储数据,kibana展示数据。

1. Zipkin简介

Zipkin 是一款开源的分布式实时数据追踪系统(Distributed Tracking System),基于 Google Dapper 的论文设计而来,由 Twitter公司开发贡献。其主要功能是聚集来自各个异构系统的实时监控数据,用来追踪微服务架构下的系统延时问题。各个微服务需要进行装备(instrument)以向 Zipkin 报告数据。Zipkin 的用户界面可以呈现一幅关联图表,以显示有多少被追踪的请求通过了每一层应用。Zipkin 以 Trace 结构表示对一次请求的追踪,又把每个 Trace 拆分为若干个有依赖关系的 Span。在微服务架构中,一次用户请求可能会由后台若干个服务负责处理,那么每个处理请求的服务就可以理解为一个 Span(可以包括 API 服务,缓存服务,数据库服务以及报表服务等)。当然这个服务也可能继续请求其他的服务,因此 Span 是一个树形结构,以体现服务之间的调用关系。Zipkin 的用户界面除了可以查看 Span 的依赖关系之外,还以瀑布图的形式显示了每个 Span 的耗时情况,可以一目了然的看到各个服务的性能状况。打开每个 Span,还有更详细的数据以键值对的形式呈现,而且这些数据可以在装备应用的时候自行添加。

2.术语

  • Span:基本工作单元,例如,在一个新建的span中发送一个RPC等同于发送一个回应请求给RPC,span通过一个64位ID唯一标识,trace以另一个64位ID表示,span还有其他数据信息,比如摘要、时间戳事件、关键值注释(tags)、span的ID、以及进度ID(通常是IP地址)
    span在不断的启动和停止,同时记录了时间信息,当你创建了一个span,你必须在未来的某个时刻停止它。
  • Trace:一系列spans组成的一个树状结构,例如,如果你正在跑一个分布式大数据工程,你可能需要创建一个trace。
  • Annotation:用来及时记录一个事件的存在,一些核心annotations用来定义一个请求的开始和结束
  • cs - Client Sent -客户端发起一个请求,这个annotion描述了这个span的开始
  • sr - Server Received -服务端获得请求并准备开始处理它,如果将其sr减去cs时间戳便可得到网络延迟
  • ss - Server Sent -注解表明请求处理的完成(当请求返回客户端),如果ss减去sr时间戳便可得到服务端需要的处理请求时间
  • cr - Client Received -表明span的结束,客户端成功接收到服务端的回复,如果cr减去cs时间戳便可得到客户端从服务端获取回复的所有所需时间
    将Span和Trace在一个系统中使用Zipkin注解的过程图形化:

下图显示了系统中的Span和Trace,以及Zipkin注释:

在这里插入图片描述

N. 插一杠子

SpringCloud Finchley版本,sleuth + zipkin 不需要自己搭建zipkin server 了,直接下载jar启动即可

N.1 下载Zipkin-server jar

传送门

N.2 启动jar

普通启动

java -jar zipkin-dependencies.jar

使用ES数据源启动

$ STORAGE_TYPE=elasticsearch ES_HOSTS=host1,host2 java -jar zipkin-dependencies.jar
# To override the http port, add it to the host string
$ STORAGE_TYPE=elasticsearch ES_HOSTS=host1:9201 java -jar zipkin-dependencies.jar

可以配置相关参数,详情参见官网,地址传送门

3. 使用

下面我们自己搭建zipkin-server,可以不用自己搭建,参见:插一杠子。
本文的案例主要有三个工程 it-zipkin-server, gateway-service, user-service。
SpringBoot 2.0.4
SpringCloud Finchley

3.1 it-zipkin-server

构建zipkin服务,我使用es存储数据,要是不用es存储可以把pom和es配置干掉

1. POM依赖

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.itcloud</groupId>
    <artifactId>it-zipkin-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>it-zipkin-server</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.SR1</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <dependency>
            <groupId>io.zipkin.java</groupId>
            <artifactId>zipkin-server</artifactId>
            <version>2.11.4</version>
        </dependency>
        <dependency>
            <groupId>io.zipkin.java</groupId>
            <artifactId>zipkin-autoconfigure-ui</artifactId>
            <version>2.11.4</version>
        </dependency>
        
		<!-- 使用es存储数据-->
        <dependency>
            <groupId>io.zipkin.java</groupId>
            <artifactId>zipkin-autoconfigure-storage-elasticsearch-http</artifactId>
            <version>2.4.2</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2. 启动类
启动类添加@EnableZipkinServer

3. YML配置

server:
  port: 9411

spring:
  application:
    name: app

  #解决The bean 'characterEncodingFilter', defined in class path resource [zipkin/autoconfigure/ui/ZipkinUiAutoConfiguration.class], could not be registered. A bean with that name has already been defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/HttpEncodingAutoConfiguration.class] and overriding is disabled.Action:
  main:
    allow-bean-definition-overriding: true

#解决IllegalArgumentException: Prometheus requires that all meters with the same name have the same set of tag keys.
management:
  metrics:
    web:
      server:
        auto-time-requests: false

# ES配置
zipkin:
  storage:
    type: elasticsearch
    elasticsearch:
      hosts: localhost:9200
      cluster: elasticsearch
      index: zipkin
      index-shards: 1
      index-replicas: 1

3.2 gateway-service

1. pom依赖

<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-zuul</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-zipkin</artifactId>
			<version>RELEASE</version>
		</dependency>

	</dependencies>

2. 启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@SpringBootApplication
@EnableZuulProxy
@EnableEurekaClient
public class GatewayServiceApplication {

	public static void main(String[] args) {
		SpringApplication.run(GatewayServiceApplication.class, args);
	}
}

过滤器
给zipkin数据添加额外属性

import com.netflix.zuul.ZuulFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.stereotype.Component;


@Component
public class LoggerFilter extends ZuulFilter {

    @Autowired
    Tracer tracer;
    @Override
    public String filterType() {
        return FilterConstants.POST_TYPE;
    }

    @Override
    public int filterOrder() {
        return 1000;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {
        tracer.addTag("operator","admin");
        System.out.print(tracer.getCurrentSpan().traceIdString());
        return null;
    }
}

3. YML配置

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:2222/eureka/

server:
  port: 5000
spring:
  application:
    name: gateway-service
  sleuth:
    sampler:
      percentage: 1.0
  zipkin:
    base-url: http://localhost:9411

zuul:
  routes:
    api-a:
      path: /user-api/**
      serviceId: user-service

3.3 user-service

1. pom依赖

	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-zipkin</artifactId>
			<version>RELEASE</version>
		</dependency>

	</dependencies>

2. 启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient
public class UserServiceApplication {

	public static void main(String[] args) {
		SpringApplication.run(UserServiceApplication.class, args);
	}
}

3. yaml

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

server:
  port: 5000
spring:
  application:
    name: gateway-service
  sleuth:
    sampler:
      percentage: 1.0
  zipkin:
    base-url: http://localhost:9411

zuul:
  routes:
    api-a:
      path: /user-api/**
      serviceId: user-service

4. Controller

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping("/hi")
    public String hi(){
        return "I'm simagang";
    }
}

3.4 eureka-service

eureka 服务很简单了,不会的可以参考:it-eureka-server

4. 测试

访问http://localhost:9411 进入zipkin管理页面
在这里插入图片描述
访问http://localhost:5000/user-api/user/hi 制造数据
在这里插入图片描述

zipkin页面Find Traces效果
在这里插入图片描述
点击去详情:
在这里插入图片描述
es中数据

{
        "_index": "zipkin:span-2019-12-11",
        "_type": "span",
        "_id": "AW7zhUPt0NSlh9dQqPqa",
        "_score": 1,
        "_source": {
          "traceId": "8a97983b4a324507",
          "duration": 7868129,
          "localEndpoint": {
            "serviceName": "gateway-service",
            "ipv4": "10.100.170.120",
            "port": 5000
          },
          "timestamp_millis": 1576043618159,
          "kind": "SERVER",
          "name": "http:/user-api/user/hi",
          "id": "8a97983b4a324507",
          "timestamp": 1576043618159000,
          "tags": {
            "operator": "admin",
            "spring.instance_id": "KZX-WW-IT37613.citiccardins.com:gateway-service:5000"
          }
        }
      }

5. 源码

zipkin server源码地址传送门
其他源码很简单请自行实现

项目推荐

IT-CLOUD :IT服务管理平台,集成基础服务,中间件服务,监控告警服务等。
IT-CLOUD-ACTIVITI6 :Activiti教程源码。博文在本CSDN Activiti系列中。
IT-CLOUD-ELASTICSEARCH :elasticsearch教程源码。博文在本CSDN elasticsearch系列中。

开源项目,持续更新中,喜欢请 Star~

发布了160 篇原创文章 · 获赞 46 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/yy756127197/article/details/103494644
今日推荐