乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

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

       甘甘灰 2018-08-03

      ## 概述

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


      Zipkin 初摸

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

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

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

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

      • Reporter

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

      • Span

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

      • Trace

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

      • Transport

      一種數(shù)據(jù)傳輸?shù)姆绞?,比如最?jiǎn)單的 HTTP 方式,當(dāng)然在高并發(fā)時(shí)可以換成 Kafka 等消息隊(duì)列


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

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

      OpenZipkin libraries

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


      部署 Zipkin 服務(wù)

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

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

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

      Zipkin 可視化界面


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

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

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

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

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

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

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

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

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

      簡(jiǎn)單起見,我們用 SpringBt 來實(shí)現(xiàn)三個(gè)微服務(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 !”;
          }
      }
      

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

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

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

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

      編寫與 Zipkin 通信的工具組件

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

      為此我們需要建立一個(gè)新的基于 Maven 的 Java 項(xiàng)目: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 兩個(gè)屬性,我們最后是需要將該兩個(gè)參數(shù)提供給 ServiceA、ServiceB、ServiceC 微服務(wù)作為其 application.properties 中的 Zipkin 配置

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

      用了 lombok 之后,這個(gè)類異常簡(jiǎn)單!

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

      • 編寫 ZipkinConfiguration 類

      這個(gè)類很重要,在里面我們將 Brave 的 BraveClientHttpRequestInterceptor 攔截器注冊(cè)到 RestTemplate 的攔截器調(diào)用鏈中來收集請(qǐng)求數(shù)據(jù)到 Zipkin 中;同時(shí)還將 Brave 的 ServletHandlerInterceptor 攔截器注冊(cè)到調(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 三個(gè) SpringBt 項(xiàng)目的 application.properties 中加入 Zipkin 的配置:

      以 ServiceA 為例:

      server.port=8881
      zipkin.endpoint=http://你 Zipkin 服務(wù)所在機(jī)器的 IP:9411/api/v1/spans
      zipkin.service=servicea
      

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


      ## 實(shí)際實(shí)驗(yàn)

      1. 依賴分析

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

      點(diǎn)擊依賴分析

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

      點(diǎn)擊 ServiceB 微服務(wù)


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

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

      查找調(diào)用鏈

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

      查看 Span

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

      Find Traces  

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

      某一個(gè)具體 Trace

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

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

      參考文獻(xiàn)


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

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多