小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

微服務(wù)調(diào)用鏈追蹤中心搭建

 甘甘灰 2018-08-03

## 概述

一個完整的微服務(wù)系統(tǒng)包含多個微服務(wù)單元,各個微服務(wù)子系統(tǒng)存在互相調(diào)用的情況,形成一個 調(diào)用鏈。一個客戶端請求從發(fā)出到被響應(yīng) 經(jīng)歷了哪些組件、哪些微服務(wù)、請求總時長每個組件所花時長 等信息我們有必要了解和收集,以幫助我們定位性能瓶頸、進行性能調(diào)優(yōu),因此監(jiān)控整個微服務(wù)架構(gòu)的調(diào)用鏈?zhǔn)钟斜匾?,本文將闡述如何使用 Zipkin 搭建微服務(wù)調(diào)用鏈追蹤中心。


Zipkin 初摸

正如 Ziplin 官網(wǎng) 所描述,Zipkin 是一款分布式的追蹤系統(tǒng),其可以幫助我們收集微服務(wù)架構(gòu)中用于解決延時問題的時序數(shù)據(jù),更直白地講就是可以幫我們追蹤調(diào)用的軌跡。

Zipkin 的設(shè)計架構(gòu)如下圖所示:

Zipkin 設(shè)計架構(gòu)

要理解這張圖,需要了解一下 Zipkin 的幾個核心概念:

  • Reporter

在某個應(yīng)用中安插的用于發(fā)送數(shù)據(jù)給 Zipkin 的組件稱為 Report,目的就是用于追蹤數(shù)據(jù)收集

  • Span

微服務(wù)中調(diào)用一個組件時,從發(fā)出請求開始到被響應(yīng)的過程會持續(xù)一段時間,將這段跨度稱為 Span

  • Trace

從 Client 發(fā)出請求到完成請求處理,中間會經(jīng)歷一個調(diào)用鏈,將這一個整個過程稱為一個追蹤( Trace )。一個 Trace 可能包含多個 Span,反之每個 Span 都有一個上級的 Trace。

  • Transport

一種數(shù)據(jù)傳輸?shù)姆绞剑热缱詈唵蔚?HTTP 方式,當(dāng)然在高并發(fā)時可以換成 Kafka 等消息隊列


看了一下基本概念后,再結(jié)合上面的架構(gòu)圖,可以試著理解一下,只有裝配有 Report 組件的 Client 才能通過 Transport 來向 Zipkin 發(fā)送追蹤數(shù)據(jù)。追蹤數(shù)據(jù)由 Collector 收集器進行手機然后持久化到 Storage 之中。最后需要數(shù)據(jù)的一方,可以通過 UI 界面調(diào)用 API 接口,從而最終取到 Storage 中的數(shù)據(jù)??梢娬w流程不復(fù)雜。

Zipkin 官網(wǎng)給出了各種常見語言支持的 OpenZipkin libraries:

OpenZipkin libraries

本文接下來將 構(gòu)造微服務(wù)追蹤的實驗場景 并使用 Brave 來輔助完成微服務(wù)調(diào)用鏈追蹤中心搭建!


部署 Zipkin 服務(wù)

利用 Docker 來部署 Zipkin 服務(wù)再簡單不過了:

docker run -d -p 9411:9411 --name zipkin docker.io/openzipkin/zipkin

完成之后瀏覽器打開:localhost:9411可以看到 Zipkin 的可視化界面:

Zipkin 可視化界面


模擬微服務(wù)調(diào)用鏈

我們來構(gòu)造一個如下圖所示的調(diào)用鏈:

微服務(wù)調(diào)用鏈

圖中包含 一個客戶端 + 三個微服務(wù)

  • Client:使用 /servicea 接口消費 ServiceA 提供的服務(wù)

  • ServiceA:使用 /serviceb 接口消費 ServiceB 提供的服務(wù),端口 8881

  • ServiceB:使用 /servicec 接口消費 ServiceC 提供的服務(wù),端口 8882

  • ServiceC:提供終極服務(wù),端口 8883

為了模擬明顯的延時效果,準(zhǔn)備在每個接口的響應(yīng)中用代碼加入 3s 的延時。

簡單起見,我們用 SpringBt 來實現(xiàn)三個微服務(wù)。

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 !”;
    }
}

我們將三個微服務(wù)都啟動起來,然后瀏覽器中輸入localhost:8881/servicea來發(fā)出請求,過了 9s 之后,將取到 ServiceC 中提供的微服務(wù)接口所返回的內(nèi)容,如下圖所示:

微服務(wù)鏈?zhǔn)秸{(diào)用結(jié)果

很明顯,調(diào)用鏈可以正常 work 了!

那么接下來我們就要引入 Zipkin 來追蹤這個調(diào)用鏈的信息!

編寫與 Zipkin 通信的工具組件

從 Zipkin 官網(wǎng)我們可以知道,借助 OpenZipkin 庫 Brave,我們可以開發(fā)一個封裝 Brave 的公共組件,讓其能十分方便地嵌入到 ServiceA,ServiceB,ServiceC 服務(wù)之中,完成與 Zipkin 的通信。

為此我們需要建立一個新的基于 Maven 的 Java 項目:ZipkinTool

  • pom.xml 中加入如下依賴:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven./POM/4.0.0"
         xmlns:xsi="http://www./2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven./POM/4.0.0 http://maven./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 兩個屬性,我們最后是需要將該兩個參數(shù)提供給 ServiceA、ServiceB、ServiceC 微服務(wù)作為其 application.properties 中的 Zipkin 配置

@Data
@Component
@ConfigurationProperties("zipkin")
public class ZipkinProperties {
    private String endpoint;
    private String service;
}

用了 lombok 之后,這個類異常簡單!

[注意:關(guān)于 lombok 的用法,可以看這里]

  • 編寫 ZipkinConfiguration 類

這個類很重要,在里面我們將 Brave 的 BraveClientHttpRequestInterceptor 攔截器注冊到 RestTemplate 的攔截器調(diào)用鏈中來收集請求數(shù)據(jù)到 Zipkin 中;同時還將 Brave 的 ServletHandlerInterceptor 攔截器注冊到調(diào)用鏈中來收集響應(yīng)數(shù)據(jù)到 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 服務(wù)所在機器的 IP:9411/api/v1/spans
zipkin.service=servicea

我們最后依次啟動 ServiceA、ServiceB、和 ServiceC 三個微服務(wù),并開始實驗來收集鏈路追蹤數(shù)據(jù) !


## 實際實驗

1. 依賴分析

瀏覽器打開 Zipkin 的 UI 界面,可以查看 依賴分析

點擊依賴分析

圖中十分清晰地展示了 ServiceA、ServiceB 和 ServiceC 三個服務(wù)之間的調(diào)用關(guān)系! 注意,該圖可縮放,并且每一個元素均可以點擊,例如點擊 ServiceB 這個微服務(wù),可以看到其調(diào)用鏈的上下游!

點擊 ServiceB 微服務(wù)


2. 查找調(diào)用鏈

接下來我們看一下調(diào)用鏈相關(guān),點擊 服務(wù)名,可以看到 Zipkin 監(jiān)控到個所有服務(wù):

查找調(diào)用鏈

同時可以查看 Span,如以 ServiceA 為例,其所有 REST 接口都再下拉列表中:

查看 Span

以 ServiceA 為例,點擊 Find Traces,可以看到其所有追蹤信息:

Find Traces  

點擊某個具體 Trace,還能看到詳細(xì)的每個 Span 的信息,如下圖中,可以看到 A B C 調(diào)用過程中每個 REST 接口的詳細(xì)時間戳:

某一個具體 Trace

點擊某一個 REST 接口進去還能看到更詳細(xì)的信息,如查看 /servicec 這個 REST 接口,可以看到從發(fā)送請求到收到響應(yīng)信息的所有詳細(xì)步驟:

某一個具體 Span 詳細(xì)信息

參考文獻


    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多