微服務調用鏈追蹤中心搭建

微服務調用鏈追蹤中心搭建

 概述

一個完整的微服務系統包含多個微服務單元,各個微服務子系統存在互相調用的狀況,造成一個 調用鏈。一個客戶端請求從發出到被響應 經歷了哪些組件、哪些微服務、請求總時長、每一個組件所花時長 等信息咱們有必要了解和收集,以幫助咱們定位性能瓶頸、進行性能調優,所以監控整個微服務架構的調用鏈十分有必要,本文將闡述如何使用 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

微服務調用鏈追蹤中心搭建

相關文章
相關標籤/搜索