最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Cloud Sleuth整合zipkin過程解析

 更新時間:2019年12月10日 09:01:43   作者:海向  
這篇文章主要介紹了Spring Cloud Sleuth整合zipkin過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

這篇文章主要介紹了Spring Cloud Sleuth整合zipkin過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

SpringCloud Sleuth 簡介

Spring Cloud Sleuth為Spring Cloud實現(xiàn)了分布式跟蹤解決方案。

Spring Cloud Sleuth借鑒了Dapper的術語。

Span:基本的工作單元。Span包括一個64位的唯一ID,一個64位trace碼,描述信息,時間戳事件,key-value 注解(tags),span處理者的ID(通常為IP)。

Trace:一組Span形成的樹形結構。

Annotation:用于及時記錄存在的事件。常用的Annotation如下:

  • cs:客戶端發(fā)送(client send) 客戶端發(fā)起一個請求,表示span開始
  • sr:服務器接收(server received) 服務器接收到客戶端的請求并開始處理,sr - cs 的時間為網(wǎng)絡延遲
  • ss:服務器發(fā)送(server send) 服務器處理完請求準備返回數(shù)據(jù)給客戶端。ss - sr 的時間表示服務器端處理請求花費的時間
  • cr:客戶端接收(client received) 客戶端接收到處理結果,表示span結束。 cr - cs 的時間表示客戶端接收服務端數(shù)據(jù)的時間

下圖展示了Span和Trace在系統(tǒng)中的聯(lián)系

Sleuth 默認采用 Http 方式將 span 傳輸給 Zipkin

在application.properties文件中指定

spring.zipkin.sender.type=web

使用 RabbitMQ 異步發(fā)送 span 信息

為什么選擇 RabbitMQ 消息中間件發(fā)送 span 信息

  • sleuth 默認采用 http 通信方式,將數(shù)據(jù)傳給 zipkin 作頁面渲染,但是 http 傳輸過程中如果由于不可抗因素導致 http 通信中斷,那么此次通信的數(shù)據(jù)將會丟失。而使用中間件的話,RabbitMQ 消息隊列可以積壓千萬級別的消息,下次重連之后可以繼續(xù)消費。
  • 隨著線程增多,并發(fā)量提升之后,RabbitMQ 異步發(fā)送數(shù)據(jù)明顯更具有優(yōu)勢。
  • RabbitMQ 支持消息、隊列持久化,可以通過消息狀態(tài)落庫、重回隊列、鏡像隊列等技術手段保證其高可用。

示例

示例簡介

示例包含sleuth-search、sleuth-cart、sleuth-order三個系統(tǒng),用來模擬電商系統(tǒng)中下單的流程,用戶可以搜索商品然后立即下單,也可以搜索多個商品后加入購物車,然后下單,調用情況即 search -> cart -> order,或 search -> order。

示例使用 RestTemplate 來完成三個系統(tǒng)間的 http 請求響應,請求方式也都遵循Restful風格。

版本說明

版本一定要對應好,一些低版本的SpringBoot無法兼容新版本的SpringCloud和zipkin

工具 版本
SpringBoot 2.1.6.RELEASE
SpringCloud Greenwich.SR3
zipkin 2.16.2

項目結構

demo-cloudsleuth
  |- sleuth-search
  |- sleuth-cart
  |- sleuth-order
  pom.xml

導入依賴

  <!-- 引入 springboot 和 springcloud 父工程 -->
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.6.RELEASE</version>
    <relativePath/>
  </parent>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>Greenwich.SR3</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <dependencies>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-zipkin</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.amqp</groupId>
      <artifactId>spring-rabbit</artifactId>
    </dependency>
    <!-- Springboot 相關 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>

配置 RestTemplate,RestTemplate是SpringBoot提供的封裝好的http工具類,可以幫助我們簡化http的使用。

package com.anqi.cart.resttmplate;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {
  @Bean
  public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
    return new RestTemplate(factory);
  }

  @Bean
  public ClientHttpRequestFactory clientHttpRequestFactory() {
    SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
    factory.setConnectTimeout(5000);
    factory.setReadTimeout(5000);
    return factory;
  }
}

三個系統(tǒng)下的application.properties,端口分別是8081 8082 8083

#server.port=8081 server.port=8082
server.port=8083 
server.servlet.context-path=/

spring.zipkin.base-url=http://localhost:9411/
spring.zipkin.service.name=sleuth-cart

#使用默認 http 方式收集 span 需要配置此項
#spring.zipkin.sender.type=web

#sleuth 使用 rabbitmq 來向 zipkin 發(fā)送數(shù)據(jù)
spring.zipkin.sender.type=rabbit
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

#設置采樣率默認為 0.1 注意之前的版本是percentage 新版本中更換為 probability
spring.sleuth.sampler.probability=1

三個系統(tǒng)下的RestTemplate的配置,用來簡化 http 請求

package com.anqi.cart.resttmplate;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {
  @Bean
  public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
    return new RestTemplate(factory);
  }

  @Bean
  public ClientHttpRequestFactory clientHttpRequestFactory() {
    SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
    factory.setConnectTimeout(5000);
    factory.setReadTimeout(5000);
    return factory;
  }
}
@RequestMapping("cart")
@RestController
public class CartController {
  @Autowired
  RestTemplate restTemplate;
  @Autowired
  CartService cartService;
  private static final String orderUrl = "http://localhost:8084/order/create";

  @GetMapping("/add/{cartId}")
  public String addToCart(@PathVariable("cartId") String cartId) {
    cartService.addProductToCart(cartId, "小米8");
    ResponseEntity<String> res = restTemplate.getForEntity(orderUrl, String.class);
    return res.getBody();
  }
}
@RequestMapping("order")
@RestController
public class OrderController {
  @GetMapping("/create")
  public String creatOrder() {
    System.out.println("create order");
    return "create_order";
  }
}
@RestController
public class SearchController {
  @Autowired
  RestTemplate restTemplate;

  private static final String cartUrl = "http://localhost:8083/cart/add/1";
  private static final String orderUrl = "http://localhost:8084/order/create";

  @GetMapping("/search")
  public String search() {
    ResponseEntity<String> cartRes = restTemplate.getForEntity(cartUrl, String.class);
    ResponseEntity<String> orderRes = restTemplate.getForEntity(orderUrl, String.class);
    return "cart:" + cartRes.getBody() + "- order:" + orderRes.getBody();

  }
}

運行結果分析

默認 http 傳輸 span 信息

啟動Zipkin

java -jar zipkin-server-2.16.2-exec.jar

網(wǎng)頁中手動訪問

http://localhost:8082/search

我們訪問zipkin站點查詢調用情況

http://localhost:9411/zipkin/traces/94b954d843012ca9

可以從下圖中完整清晰的看到三個系統(tǒng)的調用關系

下圖為zipkin調用預覽,我們請求四次http://localhost:8082/search來更直觀的觀察數(shù)據(jù)。在以下界面中,較為簡潔的顯示Span的個數(shù)以及調用總時延。

我們進入一個完整的調用鏈后訪問其中的一個節(jié)點得到以下數(shù)據(jù)。

以下為一次全鏈路追蹤的詳細信息,包含7個span的所有信息,以上看到的頁面展示均有以下數(shù)據(jù)加以渲染而成。

[
 {
  "traceId": "94b954d843012ca9",
  "parentId": "bab70b1e69a5f3e3",
  "id": "96387b33a823ca8f",
  "kind": "SERVER",
  "name": "get /order/create",
  "timestamp": 1569060494069123,
  "duration": 1161,
  "localEndpoint": {
   "serviceName": "sletuth-order",
   "ipv4": "192.168.0.107"
  },
  "remoteEndpoint": {
   "ipv4": "127.0.0.1",
   "port": 49863
  },
  "tags": {
   "http.method": "GET",
   "http.path": "/order/create",
   "mvc.controller.class": "OrderController",
   "mvc.controller.method": "creatOrder"
  },
  "shared": true
 },
 {
  "traceId": "94b954d843012ca9",
  "parentId": "94b954d843012ca9",
  "id": "90f7e5cfa89e0d80",
  "kind": "SERVER",
  "name": "get /order/create",
  "timestamp": 1569060494076287,
  "duration": 1296,
  "localEndpoint": {
   "serviceName": "sletuth-order",
   "ipv4": "192.168.0.107"
  },
  "remoteEndpoint": {
   "ipv4": "127.0.0.1",
   "port": 49864
  },
  "tags": {
   "http.method": "GET",
   "http.path": "/order/create",
   "mvc.controller.class": "OrderController",
   "mvc.controller.method": "creatOrder"
  },
  "shared": true
 },
 {
  "traceId": "94b954d843012ca9",
  "parentId": "94b954d843012ca9",
  "id": "bab70b1e69a5f3e3",
  "kind": "CLIENT",
  "name": "get",
  "timestamp": 1569060494063693,
  "duration": 10374,
  "localEndpoint": {
   "serviceName": "sleuth-search",
   "ipv4": "192.168.0.107"
  },
  "tags": {
   "http.method": "GET",
   "http.path": "/cart/add/1"
  }
 },
 {
  "traceId": "94b954d843012ca9",
  "parentId": "94b954d843012ca9",
  "id": "90f7e5cfa89e0d80",
  "kind": "CLIENT",
  "name": "get",
  "timestamp": 1569060494074966,
  "duration": 2848,
  "localEndpoint": {
   "serviceName": "sleuth-search",
   "ipv4": "192.168.0.107"
  },
  "tags": {
   "http.method": "GET",
   "http.path": "/order/create"
  }
 },
 {
  "traceId": "94b954d843012ca9",
  "id": "94b954d843012ca9",
  "kind": "SERVER",
  "name": "get /search",
  "timestamp": 1569060494062631,
  "duration": 16332,
  "localEndpoint": {
   "serviceName": "sleuth-search",
   "ipv4": "192.168.0.107"
  },
  "remoteEndpoint": {
   "ipv6": "::1",
   "port": 49859
  },
  "tags": {
   "http.method": "GET",
   "http.path": "/search",
   "mvc.controller.class": "SearchController",
   "mvc.controller.method": "search"
  }
 },
 {
  "traceId": "94b954d843012ca9",
  "parentId": "bab70b1e69a5f3e3",
  "id": "96387b33a823ca8f",
  "kind": "CLIENT",
  "name": "get",
  "timestamp": 1569060494067090,
  "duration": 3197,
  "localEndpoint": {
   "serviceName": "sleuth-cart",
   "ipv4": "192.168.0.107"
  },
  "tags": {
   "http.method": "GET",
   "http.path": "/order/create"
  }
 },
 {
  "traceId": "94b954d843012ca9",
  "parentId": "94b954d843012ca9",
  "id": "bab70b1e69a5f3e3",
  "kind": "SERVER",
  "name": "get /cart/add/{cartid}",
  "timestamp": 1569060494066140,
  "duration": 8150,
  "localEndpoint": {
   "serviceName": "sleuth-cart",
   "ipv4": "192.168.0.107"
  },
  "remoteEndpoint": {
   "ipv4": "127.0.0.1",
   "port": 49862
  },
  "tags": {
   "http.method": "GET",
   "http.path": "/cart/add/1",
   "mvc.controller.class": "CartController",
   "mvc.controller.method": "addToCart"
  },
  "shared": true
 }
]

使用 RabbitMQ 情況

啟動 zipkin,注意參數(shù)

java -jar zipkin-server-2.16.2-exec.jar --RABBIT_ADDRESSES=localhost:5672 --RABBIT_USER=guest --RABBIT_PASSWORD=guest --RABBIT_VIRTUAL_HOST=/

啟動 rabbitmq

rabbitmq-server

在測試的時候發(fā)現(xiàn) mq 和以上方式時延相差無幾,但是隨著線程數(shù)的增加也就是并發(fā)量的增加,mq 傳輸時延將會大大低于 http。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • 使用Spring Data Redis實現(xiàn)數(shù)據(jù)緩存的方法

    使用Spring Data Redis實現(xiàn)數(shù)據(jù)緩存的方法

    目前在系統(tǒng)架構設計中使用Redis實現(xiàn)緩存,這篇文章主要介紹了使用Spring Data Redis實現(xiàn)數(shù)據(jù)緩存的方法,具有一定的參考價值,需要的朋友可以參考下
    2018-11-11
  • SpringBoot java-jar命令行啟動原理解析

    SpringBoot java-jar命令行啟動原理解析

    這篇文章主要介紹了SpringBoot java-jar命令行啟動原理解析,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • 以Java代碼為例講解設計模式中的簡單工廠模式

    以Java代碼為例講解設計模式中的簡單工廠模式

    簡單來說,工廠模式就是按照需求來返回一個類型的對象,使用工廠模式的意義就是,如果對象的實例化與代碼依賴太大的話,不方便進行擴展和維護,使用工廠的目的就是使對象的實例化與主程序代碼就行解耦.來具體看一下:
    2016-05-05
  • Java在控制臺輸出帶顏色字符的2種方式詳解

    Java在控制臺輸出帶顏色字符的2種方式詳解

    這篇文章主要給大家介紹了關于Java在控制臺輸出帶顏色字符的2種方式,文中通過實例代碼以及圖文介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2022-01-01
  • Java Arrays.sort()用法詳解

    Java Arrays.sort()用法詳解

    這篇文章主要介紹了Java Arrays.sort()用法詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下
    2021-08-08
  • Java十大經(jīng)典排序算法的實現(xiàn)圖解

    Java十大經(jīng)典排序算法的實現(xiàn)圖解

    Java常見的排序算法有:插入排序、希爾排序、選擇排序、冒泡排序、歸并排序、快速排序、堆排序、基數(shù)排序等。本文詳解介紹Java十大十大經(jīng)典排序算法的實現(xiàn)以及圖解,需要的可以參考一下
    2022-03-03
  • JUnit4 Hamcrest匹配器常用方法總結

    JUnit4 Hamcrest匹配器常用方法總結

    這篇文章主要介紹了JUnit4 Hamcrest匹配器常用方法總結,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-11-11
  • SpringBoot通過@Scheduled實現(xiàn)定時任務及單線程運行問題解決

    SpringBoot通過@Scheduled實現(xiàn)定時任務及單線程運行問題解決

    Scheduled定時任務是Spring boot自身提供的功能,所以不需要引入Maven依賴包,下面這篇文章主要給大家介紹了關于SpringBoot通過@Scheduled實現(xiàn)定時任務以及問題解決的相關資料,需要的朋友可以參考下
    2023-02-02
  • springboot結合mybatis-plus快速生成項目模板的方法

    springboot結合mybatis-plus快速生成項目模板的方法

    Mybatis-Plus是一個 Mybatis 的增強工具,在 Mybatis 的基礎上只做增強不做改變,為簡化開發(fā)、提高效率而生,接下來通過本文給大家分享springboot結合mybatis-plus快速生成項目模板的方法,感興趣的朋友一起看看吧
    2021-06-06
  • java中重寫equals()方法的同時要重寫hashcode()方法(詳解)

    java中重寫equals()方法的同時要重寫hashcode()方法(詳解)

    下面小編就為大家?guī)硪黄猨ava中重寫equals()方法的同時要重寫hashcode()方法(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05

最新評論

陈巴尔虎旗| 黔西| 巫山县| 文水县| 和田县| 东明县| 滦南县| 惠东县| 浙江省| 自治县| 广丰县| 子洲县| 信丰县| 钦州市| 秦安县| 芦溪县| 伊川县| 绥江县| 九龙坡区| 凤冈县| 宜章县| 德化县| 蒲城县| 夏津县| 和林格尔县| 钟祥市| 洪洞县| 亚东县| 临武县| 曲沃县| 钦州市| 勃利县| 文化| 临泽县| 洪湖市| 容城县| 当雄县| 盱眙县| 乡城县| 皮山县| 喀喇沁旗|