微服务调用链追踪中心搭建

微服务调用链追踪中心搭建

 概述

一个完整的微服务系统包含多个微服务单元,各个微服务子系统存在互相调用的状况,造成一个 调用链。一个客户端请求从发出到被响应 经历了哪些组件、哪些微服务、请求总时长、每一个组件所花时长 等信息咱们有必要了解和收集,以帮助咱们定位性能瓶颈、进行性能调优,所以监控整个微服务架构的调用链十分有必要,本文将阐述如何使用 Zipkin 搭建微服务调用链追踪中心。web

Zipkin初摸

正如 Ziplin官网 所描述,Zipkin是一款分布式的追踪系统,其能够帮助咱们收集微服务架构中用于解决延时问题的时序数据,更直白地讲就是能够帮咱们追踪调用的轨迹。spring

Zipkin的设计架构以下图所示:
微服务调用链追踪中心搭建
要理解这张图,须要了解一下Zipkin的几个核心概念:docker

  • Reporter

在某个应用中安插的用于发送数据给Zipkin的组件称为Report,目的就是用于追踪数据收集apache

  • Span

微服务中调用一个组件时,从发出请求开始到被响应的过程会持续一段时间,将这段跨度称为Spanapi

  • Trace

从Client发出请求到完成请求处理,中间会经历一个调用链,将这一个整个过程称为一个追踪(Trace)。一个Trace可能包含多个Span,反之每一个Span都有一个上级的Trace。浏览器

  • Transport

一种数据传输的方式,好比最简单的HTTP方式,固然在高并发时能够换成Kafka等消息队列架构

看了一下基本概念后,再结合上面的架构图,能够试着理解一下,只有装配有Report组件的Client才能经过Transport来向Zipkin发送追踪数据。追踪数据由Collector收集器进行手机而后持久化到Storage之中。最后须要数据的一方,能够经过UI界面调用API接口,从而最终取到Storage中的数据。可见总体流程不复杂。并发

Zipkin官网给出了各类常见语言支持的OpenZipkin libraries:mvc

微服务调用链追踪中心搭建

本文接下来将 构造微服务追踪的实验场景 并使用 Brave 来辅助完成微服务调用链追踪中心搭建!
部署Zipkin服务app

利用Docker来部署Zipkin服务再简单不过了:

docker run -d -p 9411:9411 \

--name zipkin \

docker.io/openzipkin/zipkin

完成以后浏览器打开: localhost:9411能够看到Zipkin的可视化界面:

微服务调用链追踪中心搭建

模拟微服务调用链

咱们来构造一个以下图所示的调用链:

微服务调用链追踪中心搭建

图中包含 一个客户端 + 三个微服务:

  • Client:使用/servicea接口消费ServiceA提供的服务

  • ServiceA:使用/serviceb接口消费ServiceB提供的服务,端口8881

  • ServiceB:使用/servicec接口消费ServiceC提供的服务,端口8882

  • ServiceC:提供终极服务,端口8883

为了模拟明显的延时效果,准备在每一个接口的响应中用代码加入3s的延时。

简单起见,咱们用SpringBt来实现三个微服务。

ServiceA的控制器代码以下:

@RestController

public class ServiceAContorller {

    @Autowired

    private RestTemplate restTemplate;

    @GetMapping("/servicea”)

    public String servicea() {

        try {

            Thread.sleep( 3000 );

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

        return restTemplate.getForObject("http://localhost:8882/serviceb", String.class);

    }

}

ServiceB的代码以下:

@RestController

public class ServiceBContorller {

    @Autowired

    private RestTemplate restTemplate;

    @GetMapping("/serviceb”)

    public String serviceb() {

        try {

            Thread.sleep( 3000 );

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

        return restTemplate.getForObject("http://localhost:8883/servicec", String.class);

    }

}

ServiceC的代码以下:

@RestController

public class ServiceCContorller {

    @Autowired

    private RestTemplate restTemplate;

    @GetMapping("/servicec”)

    public String servicec() {

        try {

            Thread.sleep( 3000 );

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

        return "Now, we reach the terminal call: servicec !”;

    }

}

咱们将三个微服务都启动起来,而后浏览器中输入 localhost:8881/servicea来发出请求,过了9s以后,将取到ServiceC中提供的微服务接口所返回的内容,以下图所示:

微服务调用链追踪中心搭建
很明显,调用链能够正常work了!

那么接下来咱们就要引入Zipkin来追踪这个调用链的信息!

编写与Zipkin通讯的工具组件

从Zipkin官网咱们能够知道,借助OpenZipkin库Brave,咱们能够开发一个封装Brave的公共组件,让其能十分方便地嵌入到ServiceA,ServiceB,ServiceC服务之中,完成与Zipkin的通讯。

为此咱们须要创建一个新的基于Maven的Java项目: ZipkinTool

  • pom.xml中加入以下依赖:
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">

        <modelVersion>4.0.0</modelVersion>

        <groupId>com.hansonwang99</groupId>

        <artifactId>ZipkinTool</artifactId>

        <version>1.0-SNAPSHOT</version>

        <build>

            <plugins>

                <plugin>

                    <groupId>org.apache.maven.plugins</groupId>

                    <artifactId>maven-compiler-plugin</artifactId>

                    <configuration>

                        <source>6</source>

                        <target>6</target>

                    </configuration>

                </plugin>

            </plugins>

        </build>

        <packaging>jar</packaging>

        <dependencies>

            <dependency>

                <groupId>org.springframework.boot</groupId>

                <artifactId>spring-boot</artifactId>

                <version>2.0.1.RELEASE</version>

                <scope>provided</scope>

            </dependency>

            <dependency>

                <groupId>org.springframework</groupId>

                <artifactId>spring-webmvc</artifactId>

                <version>4.3.7.RELEASE</version>

                <scope>provided</scope>

            </dependency>

            <dependency>

                <groupId>io.zipkin.brave</groupId>

                <artifactId>brave-spring-web-servlet-interceptor</artifactId>

                <version>4.0.6</version>

            </dependency>

            <dependency>

                <groupId>io.zipkin.brave</groupId>

                <artifactId>brave-spring-resttemplate-interceptors</artifactId>

                <version>4.0.6</version>

            </dependency>

            <dependency>

                <groupId>io.zipkin.reporter</groupId>

                <artifactId>zipkin-sender-okhttp3</artifactId>

                <version>0.6.12</version>

            </dependency>

            <dependency>

                <groupId>org.projectlombok</groupId>

                <artifactId>lombok</artifactId>

                <version>RELEASE</version>

                <scope>compile</scope>

            </dependency>

        </dependencies>

    </project>
  • 编写ZipkinProperties类

其包含endpoint和service两个属性,咱们最后是须要将该两个参数提供给ServiceA、ServiceB、ServiceC微服务做为其application.properties中的Zipkin配置

@Data

@Component

@ConfigurationProperties("zipkin")

public class ZipkinProperties {

    private String endpoint;

    private String service;

}

用了 lombok以后,这个类异常简单!

  • 编写ZipkinConfiguration类

这个类很重要,在里面咱们将Brave的BraveClientHttpRequestInterceptor拦截器注册到RestTemplate的拦截器调用链中来收集请求数据到Zipkin中;同时还将Brave的ServletHandlerInterceptor拦截器注册到调用链中来收集响应数据到Zipkin中

上代码吧:

@Configuration

@Import({RestTemplate.class, BraveClientHttpRequestInterceptor.class, ServletHandlerInterceptor.class})

public class ZipkinConfiguration extends WebMvcConfigurerAdapter {

    @Autowired

    private ZipkinProperties zipkinProperties;

    @Autowired

    private RestTemplate restTemplate;

    @Autowired

    private BraveClientHttpRequestInterceptor clientInterceptor;

    @Autowired

    private ServletHandlerInterceptor serverInterceptor;

    @Bean

    public Sender sender() {

        return OkHttpSender.create( zipkinProperties.getEndpoint() );

    }

    @Bean

    public Reporter<Span> reporter() {

        return AsyncReporter.builder(sender()).build();

    }

    @Bean

    public Brave brave() {

        return new Brave.Builder(zipkinProperties.getService()).reporter(reporter()).build();

    }

    @Bean

    public SpanNameProvider spanNameProvider() {

        return new SpanNameProvider() {

            @Override

            public String spanName(HttpRequest httpRequest) {

                return String.format(

                        "%s %s",

                        httpRequest.getHttpMethod(),

                        httpRequest.getUri().getPath()

                );

            }

        };

    }

    @PostConstruct

    public void init() {

        List<ClientHttpRequestInterceptor> interceptors = restTemplate.getInterceptors();

        interceptors.add(clientInterceptor);

        restTemplate.setInterceptors(interceptors);

    }

    @Override

    public void addInterceptors(InterceptorRegistry registry) {

        registry.addInterceptor(serverInterceptor);

    }

}

ZipkinTool完成之后,咱们须要在ServiceA、ServiceB、ServiceC三个SpringBt项目的application.properties中加入Zipkin的配置:

以ServiceA为例:

server.port=8881

zipkin.endpoint=http://你Zipkin服务所在机器的IP:9411/api/v1/spans

zipkin.service=servicea

咱们最后依次启动ServiceA、ServiceB、和ServiceC三个微服务,并开始实验来收集链路追踪数据 !

 实际实验

1. 依赖分析

浏览器打开Zipkin的UI界面,能够查看 依赖分析:

微服务调用链追踪中心搭建

图中十分清晰地展现了ServiceA、ServiceB和ServiceC三个服务之间的调用关系! 注意,该图可缩放,而且每个元素都可以点击,例如点击 ServiceB这个微服务,能够看到其调用链的上下游!

微服务调用链追踪中心搭建

2. 查找调用链

接下来咱们看一下调用链相关,点击 服务名,能够看到Zipkin监控到个全部服务:

微服务调用链追踪中心搭建

同时能够查看Span,如以ServiceA为例,其全部REST接口都再下拉列表中:

微服务调用链追踪中心搭建

以ServiceA为例,点击 Find Traces,能够看到其全部追踪信息:

微服务调用链追踪中心搭建

点击某个具体Trace,还能看到详细的每一个Span的信息,以下图中,能够看到 A → B → C 调用过程当中每一个REST接口的详细时间戳:

微服务调用链追踪中心搭建

点击某一个REST接口进去还能看到更详细的信息,如查看/servicec这个REST接口,能够看到从发送请求到收到响应信息的全部详细步骤:

微服务调用链追踪中心搭建

后记

做者一些其余容器化应用方面的文章:

  • Docker容器可视化监控中心搭建

  • 利用K8S技术栈打造我的私有云连载文章

更多务实、能看懂、可复现的 原创文章在公众号CodeSheep

微服务调用链追踪中心搭建

相关文章
相关标签/搜索