Spring Cloud Sleuth綜合整理

轉(zhuǎn)載:https://blog.csdn.net/niugang0920/article/details/81259990

1.介紹

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

1.1術(shù)語

Spring Cloud Sleuth借用了Google

Dapper的術(shù)語。

Span:工作的基本單位。例如,發(fā)送RPC是一個新的跨度,就像發(fā)送響應(yīng)到RPC一樣。Span是由一個唯一的64位ID來標識的,而另一個64位ID用于跟蹤。span還具有其他數(shù)據(jù),如描述、時間戳事件、鍵值標注(標記)、導(dǎo)致它們的span的ID和進程ID(通常是IP地址)。

可以啟動和停止跨度,并跟蹤其時間信息。 創(chuàng)建跨度后,必須在將來的某個時刻停止它。

啟動跟蹤的初始范圍稱為根跨度。 該范圍的ID值等于跟蹤ID。

Trace:一組span形成樹狀結(jié)構(gòu)。 例如,如果運行分布式大數(shù)據(jù)存儲,則可能由PUT請求形成跟蹤。

注解:用于及時記錄事件的存在。 使用Brave工具,我們不再需要為Zipkin設(shè)置特殊事件,以了解客戶端和服務(wù)器是誰,請求開始的位置以及結(jié)束位置。

cs:客戶已發(fā)送。 客戶提出了請求。 此注釋表示跨度的開始。
sr:Server Received:服務(wù)器端獲得請求并開始處理它。 從此時間戳中減去cs時間戳?xí)@示網(wǎng)絡(luò)延遲。
ss:服務(wù)器已發(fā)送。 在完成請求處理時(當響應(yīng)被發(fā)送回客戶端時)注釋。 從此時間戳中減去sr時間戳?xí)@示服務(wù)器端處理請求所需的時間。
cr:客戶收到了。 表示跨度的結(jié)束。 客戶端已成功收到服務(wù)器端的響應(yīng)。 從此時間戳中減去cs時間戳?xí)@示客戶端從服務(wù)器接收響應(yīng)所需的全部時間。

下圖顯示了Span和Trace在系統(tǒng)中的外觀以及Zipkin注解:


image.png

注釋的每種顏色表示跨度(有七個跨度 - 從A到G)。 請考慮以下注釋:

此注釋表示當前跨度的Trace Id設(shè)置為X,Span Id設(shè)置為D.此外,還發(fā)生了Client Sent事件。

Trace Id = X
Span Id = D
Client Sent

下圖顯示了跨度的父子關(guān)系:


image.png

1.2目的

以下部分參考上圖中顯示的示例。

1.2.1使用Zipkin進行分布式跟蹤

這個例子有七個跨度。如果你在Zipkin中查看跟蹤,你可以在第二個跟蹤中看到這個數(shù)字,如下圖所示:


image.png

但是,如果選擇特定跟蹤,則可以看到四個跨度,如下圖所示:


image.png

選擇特定跟蹤時,您會看到合并的跨度。 這意味著,如果通過Server Received和Server Sent或Client Received和Client Sent annotations向Zipkin發(fā)送了兩個跨度,則它們將顯示為單個跨度。

在這種情況下,為什么七個和四個跨度之間存在差異?

兩個跨度來自http:/start span。它具有Server Received(sr)和Server Sent(ss)注釋。
從Service1到service2到http:/foo端點的RPC調(diào)用有兩個跨度??蛻舳税l(fā)送(cs)和客戶端接收(cr)事件發(fā)生在service1端。 Server Received(sr)和Server Sent(ss)事件發(fā)生在service2端。這兩個跨度形成一個與RPC調(diào)用相關(guān)的邏輯跨度。
兩個跨度來自從service2到service3的RPC調(diào)用到http:/bar端點??蛻舳税l(fā)送(cs)和客戶端接收(cr)事件發(fā)生在service2端。 Server Received(sr)和Server Sent(ss)事件發(fā)生在service3端。這兩個跨度形成一個與RPC調(diào)用相關(guān)的邏輯跨度。
兩個跨度來自從service2到service4的RPC調(diào)用到http:/baz端點??蛻舳税l(fā)送(cs)和客戶端接收(cr)事件發(fā)生在service2端。服務(wù)器已接收(sr)和服務(wù)器已發(fā)送(ss)事件發(fā)生在service4端。這兩個跨度形成一個與RPC調(diào)用相關(guān)的邏輯跨度。
因此,如果我們計算物理跨度,我們有一個來自http:/ start,兩個來自service1調(diào)用service2,兩個來自service2調(diào)用service3,兩個來自service2調(diào)用service4。 總之,我們總共有七個跨度。

從邏輯上講,我們看到了四個總Spans的信息,因為我們有一個與service1的傳入請求相關(guān)的span和三個與RPC調(diào)用相關(guān)的spans。

1.2.2 可視化錯誤

Zipkin允許您可視化Trace中的錯誤。 當拋出一個異常并且沒有被捕獲時,我們在跨度上設(shè)置了適當?shù)臉撕?,然后Zipkin可以正確地著色。 您可以在Trace列表中看到一條紅色的跡線。 這似乎是因為拋出異常。

如果單擊該跟蹤,您將看到類似的圖片,如下所示:


image.png

跨度顯示錯誤的原因以及與之相關(guān)的整個堆棧跟蹤。


image.png

1.2.3日志相關(guān)

當使用grep掃描一個等于(例如)2485ec27856c56f4的Trace ID來讀取這四個應(yīng)用程序的日志時,您會得到如下輸出:

service1.log:2016-02-26 11:15:47.561  INFO [service1,2485ec27856c56f4,2485ec27856c56f4,true] 68058 --- [nio-8081-exec-1] i.s.c.sleuth.docs.service1.Application   : Hello from service1. Calling service2
service2.log:2016-02-26 11:15:47.710  INFO [service2,2485ec27856c56f4,9aa10ee6fbde75fa,true] 68059 --- [nio-8082-exec-1] i.s.c.sleuth.docs.service2.Application   : Hello from service2. Calling service3 and then service4
service3.log:2016-02-26 11:15:47.895  INFO [service3,2485ec27856c56f4,1210be13194bfe5,true] 68060 --- [nio-8083-exec-1] i.s.c.sleuth.docs.service3.Application   : Hello from service3
service2.log:2016-02-26 11:15:47.924  INFO [service2,2485ec27856c56f4,9aa10ee6fbde75fa,true] 68059 --- [nio-8082-exec-1] i.s.c.sleuth.docs.service2.Application   : Got response from service3 [Hello from service3]
service4.log:2016-02-26 11:15:48.134  INFO [service4,2485ec27856c56f4,1b1845262ffba49d,true] 68061 --- [nio-8084-exec-1] i.s.c.sleuth.docs.service4.Application   : Hello from service4
service2.log:2016-02-26 11:15:48.156  INFO [service2,2485ec27856c56f4,9aa10ee6fbde75fa,true] 68059 --- [nio-8082-exec-1] i.s.c.sleuth.docs.service2.Application   : Got response from service4 [Hello from service4]
service1.log:2016-02-26 11:15:48.182  INFO [service1,2485ec27856c56f4,2485ec27856c56f4,true] 68058 --- [nio-8081-exec-1] i.s.c.sleuth.docs.service1.Application   : Got response from service2 [Hello from service2, response from service3 [Hello from service3] and from service4 [Hello from service4]]

如果使用日志聚合工具(例如Kibana,Splunk等),則可以對發(fā)生的事件進行排序。 Kibana的一個例子類似于下圖:


image.png

如果要使用Logstash,以下列表顯示了Logstash的Grok模式:

Logstash是一個具有實時流水線功能的開源數(shù)據(jù)收集引擎。 Logstash可以動態(tài)統(tǒng)一來自不同來源的數(shù)據(jù),并將數(shù)據(jù)標準化為您選擇的目的地。 為各種高級下游分析和可視化用例清理和民主化所有數(shù)據(jù)。

雖然Logstash最初推動了日志收集的創(chuàng)新,但其功能遠遠超出了該用例。 任何類型的事件都可以通過廣泛的輸入,過濾和輸出插件進行豐富和轉(zhuǎn)換,許多本機編解碼器進一步簡化了攝取過程。 Logstash通過利用更大容量和更多數(shù)據(jù)來加速您的見解。

Grok是Logstash過濾器的基礎(chǔ),可以無處不在地用于從非結(jié)構(gòu)化數(shù)據(jù)中獲取結(jié)構(gòu)。 享受豐富的集成模式,旨在幫助快速解決Web,系統(tǒng),網(wǎng)絡(luò)和其他類型的事件格式。

filter {
       # pattern matching logback pattern
       grok {
              match => { "message" => "%{TIMESTAMP_ISO8601:timestamp}\s+%{LOGLEVEL:severity}\s+\[%{DATA:service},%{DATA:trace},%{DATA:span},%{DATA:exportable}\]\s+%{DATA:pid}\s+---\s+\[%{DATA:thread}\]\s+%{DATA:class}\s+:\s+%{GREEDYDATA:rest}" }
       }
}

注意:如果要將Grok與Cloud Foundry中的日志一起使用,則必須使用以下模式:

filter {
       # pattern matching logback pattern
       grok {
              match => { "message" => "(?m)OUT\s+%{TIMESTAMP_ISO8601:timestamp}\s+%{LOGLEVEL:severity}\s+\[%{DATA:service},%{DATA:trace},%{DATA:span},%{DATA:exportable}\]\s+%{DATA:pid}\s+---\s+\[%{DATA:thread}\]\s+%{DATA:class}\s+:\s+%{GREEDYDATA:rest}" }
       }
}

使用Logstash的JSON Logback

通常,您不希望將日志存儲在一個文本文件中,而是存儲在一個JSON文件中,logstash可以立即選擇該文件。為此,您必須執(zhí)行以下操作(為了可讀性,我們傳遞groupId:artifactId:version notation中的依賴關(guān)系)。

依賴關(guān)系設(shè)置

1.確保Logback位于類路徑上(ch.qos.logback:logback-core)。

    <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>${logback.version}</version>
        </dependency>

2.添加Logstash Logback編碼。 例如,要使用版本4.6,請?zhí)砑觧et.logstash.logback:logstash-logback-encoder:4.6。

        <dependency>
            <groupId>net.logstash.logback</groupId>
            <artifactId>logstash-logback-encoder</artifactId>
            <version>4.6</version>
        </dependency>

3.增加Logback

請考慮以下Logback配置文件示例(名為logback-spring.xml)。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    
    <springProperty scope="context" name="springAppName" source="spring.application.name"/>
    <!-- Example for logging into the build folder of your project -->
    <property name="LOG_FILE" value="${BUILD_FOLDER:-build}/${springAppName}"/>
 
    <!-- You can override this to have a custom pattern -->
    <property name="CONSOLE_LOG_PATTERN"
              value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
 
    <!-- Appender to log to console -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <!-- Minimum logging level to be presented in the console logs-->
            <level>DEBUG</level>
        </filter>
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
    </appender>
 
    <!-- Appender to log to file -->
    <appender name="flatfile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_FILE}</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.gz</fileNamePattern>
            <maxHistory>7</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
    </appender>
    
    <!-- Appender to log to file in a JSON format -->
    <appender name="logstash" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_FILE}.json</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_FILE}.json.%d{yyyy-MM-dd}.gz</fileNamePattern>
            <maxHistory>7</maxHistory>
        </rollingPolicy>
        <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
            <providers>
                <timestamp>
                    <timeZone>UTC</timeZone>
                </timestamp>
                <pattern>
                    <pattern>
                        {
                        "severity": "%level",
                        "service": "${springAppName:-}",
                        "trace": "%X{X-B3-TraceId:-}",
                        "span": "%X{X-B3-SpanId:-}",
                        "parent": "%X{X-B3-ParentSpanId:-}",
                        "exportable": "%X{X-Span-Export:-}",
                        "pid": "${PID:-}",
                        "thread": "%thread",
                        "class": "%logger{40}",
                        "rest": "%message"
                        }
                    </pattern>
                </pattern>
            </providers>
        </encoder>
    </appender>
    
    <root level="INFO">
        <appender-ref ref="console"/>
        <!-- uncomment this to have also JSON logs -->
        <!--<appender-ref ref="logstash"/>-->
        <!--<appender-ref ref="flatfile"/>-->
    </root>
</configuration>

那個Logback配置文件:

  • 將來自應(yīng)用程序的信息以JSON格式記錄到build/${spring.application.name}.json文件中。(在項目中)
  • 已注釋掉兩個額外的appender:控制臺和標準日志文件。
  • 具有與上一節(jié)中介紹的相同的日志記錄模式。
    如果使用自定義logback-spring.xml,則必須在bootstrap.properties(yml)而不是應(yīng)用application.properties(yml)中傳遞spring.application.name。 否則,您的自定義logback文件無法正確讀取該屬性。

1.3為項目添加Sleuth

重要
要確保您的應(yīng)用程序名稱在Zipkin中正確顯示,請在bootstrap.yml中設(shè)置spring.application.name屬性。

1.3.1只有Sleuth

<dependencyManagement> 
      <dependencies>
          <dependency>
              <groupId>org.springframework.cloud</groupId>
              <artifactId>spring-cloud-dependencies</artifactId>
              <version>${release.train.version}</version>
              <type>pom</type>
              <scope>import</scope>
          </dependency>
      </dependencies>
</dependencyManagement>
 
<dependency> 
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>

我們建議您通過Spring BOM添加依賴關(guān)系管理,這樣您就無需自行管理版本?!緎pringboot springcloud推薦的添加方式】

將依賴項添加到spring-cloud-starter-sleuth。

1.3.2通過HTTP與Zipkin的Sleuth

<dependencyManagement> 
      <dependencies>
          <dependency>
              <groupId>org.springframework.cloud</groupId>
              <artifactId>spring-cloud-dependencies</artifactId>
              <version>${release.train.version}</version>
              <type>pom</type>
              <scope>import</scope>
          </dependency>
      </dependencies>
</dependencyManagement>
 
<dependency> 
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>

我們建議您通過Spring BOM添加依賴關(guān)系管理,這樣您就無需自行管理版本。
將依賴項添加到spring-cloud-starter-zipkin。

如果spring-cloud-sleuth-zipkin可用,則該應(yīng)用程序?qū)⑼ㄟ^HTTP生成并收集與Zipkin兼容的跟蹤。 默認情況下,它將它們發(fā)送到localhost(端口9411)上的Zipkin收集器服務(wù)。 使用spring.zipkin.baseUrl配置服務(wù)的位置。

注意:您可以設(shè)置logging.level.org.springframework.web.servlet.DispatcherServlet = DEBUG,而不是在處理程序中明確記錄請求。

注意:如果使用Zipkin,請通過設(shè)置(對于2.0.x)spring.sleuth.sampler.probability或(直到2.0.x)spring.sleuth.sampler.percentage(默認值:0.1,這是 10%,Sleuth會忽略掉大量的span)。 否則,您可能會認為偵探無效,因為它忽略了一些跨度。

注意:設(shè)置spring.application.name = bar(例如)以查看服務(wù)名稱以及跟蹤和跨度ID。

1.3.3在RabbitMQ或Kafka上使用Zipkin的Sleuth

如果您想使用RabbitMQ或Kafka而不是HTTP,請?zhí)砑觭pring-rabbit或spring-kafka依賴項。默認的目的地名是zipkin。
如果使用Kafka,則必須設(shè)置屬性spring.zipkin.sender。類型相應(yīng)的屬性:

spring.zipkin.sender.type: kafka

警告:spring-cloud-sleuth-stream已棄用且與這些目標不兼容。

如果你想通過RabbitMQ上的Sleuth,添加spring-cloud-starter-zipkin和spring-rabbit依賴項。

Maven

<dependencyManagement> 
      <dependencies>
          <dependency>
              <groupId>org.springframework.cloud</groupId>
              <artifactId>spring-cloud-dependencies</artifactId>
              <version>${release.train.version}</version>
              <type>pom</type>
              <scope>import</scope>
          </dependency>
      </dependencies>
</dependencyManagement>
 
<dependency> 
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<dependency> 
    <groupId>org.springframework.amqp</groupId>
    <artifactId>spring-rabbit</artifactId>
</dependency>

我們建議您通過Spring BOM添加依賴項管理,這樣您就不需要自己管理版本。
將依賴項添加到spring-cloud-starter-zipkin。這樣,所有嵌套的依賴項都會被下載。
要自動配置RabbitMQ,請?zhí)砑觭pring-rabbit依賴項。

2.發(fā)送span到Zipkin

默認情況下,如果將spring-cloud-starter-zipkin添加為項目的依賴項,則當跨度關(guān)閉時,它將通過HTTP發(fā)送到Zipkin。 通信是異步的。 您可以通過設(shè)置spring.zipkin.baseUrl屬性來配置URL,如下所示:

spring.zipkin.baseUrl: http://192.168.99.100:9411/

如果您想通過服務(wù)發(fā)現(xiàn)找到Zipkin,您可以在URL中傳遞Zipkin的服務(wù)ID,如以下zipkinserver服務(wù)ID示例所示:

spring.zipkin.baseUrl: http://zipkinserver/

要禁用此功能,只需將spring.zipkin.discoveryClientEnabled設(shè)置為false。

啟用Discovery Client功能后,Sleuth使用LoadBalancerClient查找Zipkin Server的URL。 這意味著您可以設(shè)置負載平衡配置,例如 通過功能區(qū)

zipkinserver:
  ribbon:
    ListOfServers: host1,host2

如果您在類路徑上一起使用web,rabbit或kafka,則可能需要選擇要將spans發(fā)送到zipkin的方法。 為此,請將web,rabbit或kafka設(shè)置為spring.zipkin.sender.type屬性。 以下示例顯示為web設(shè)置發(fā)件人類型:

spring.zipkin.sender.type: web

3.Span數(shù)據(jù)作為消息

您可以通過將spring-cloud-sleuth-stream jar包含為依賴項來累積和發(fā)送Spring Cloud的跨度數(shù)據(jù),并添加Channel Binder實現(xiàn)(例如,用于RabbitMQ的spring-cloud-starter-stream-rabbit或Kafka的spring-cloud-starter-stream-kafka)。 這將自動將您的應(yīng)用程序轉(zhuǎn)換為有效負載類型為Spans的消息的生成者。

Zipkin消費者

有一個特殊的便利注釋,用于為Span數(shù)據(jù)設(shè)置消息使用者并將其推送到Zipkin SpanStore。

@SpringBootApplication
@EnableZipkinStreamServer
public class Consumer {
    public static void main(String[] args) {
        SpringApplication.run(Consumer.class, args);
    }
}

將通過Spring Cloud Stream Binder監(jiān)聽您提供的任何傳輸?shù)腟pan數(shù)據(jù)(例如,包括用于RabbitMQ的spring-cloud-starter-stream-rabbit,以及Redis和Kafka的類似啟動器)。 如果添加以下UI依賴項

<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-ui</artifactId>

默認的SpanStore是內(nèi)存中的(適用于演示和快速入門)。 對于更強大的解決方案,您可以將MySQL和spring-boot-starter-jdbc添加到類路徑中,并通過配置啟用JDBC SpanStore。

spring:
  rabbitmq:
    host: ${RABBIT_HOST:localhost}
  datasource:
    schema: classpath:/mysql.sql
    url: jdbc:mysql://${MYSQL_HOST:localhost}/test
    username: root
    password: root
# Switch this on to create the schema on startup:
    initialize: true
    continueOnError: true
  sleuth:
    enabled: false
zipkin:
  storage:
    type: mysql

mysql腳本

CREATE TABLE IF NOT EXISTS zipkin_spans (
  `trace_id_high` BIGINT NOT NULL DEFAULT 0 COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit',
  `trace_id` BIGINT NOT NULL,
  `id` BIGINT NOT NULL,
  `name` VARCHAR(255) NOT NULL,
  `parent_id` BIGINT,
  `debug` BIT(1),
  `start_ts` BIGINT COMMENT 'Span.timestamp(): epoch micros used for endTs query and to implement TTL',
  `duration` BIGINT COMMENT 'Span.duration(): micros used for minDuration and maxDuration query'
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;
 
ALTER TABLE zipkin_spans ADD UNIQUE KEY(`trace_id_high`, `trace_id`, `id`) COMMENT 'ignore insert on duplicate';
ALTER TABLE zipkin_spans ADD INDEX(`trace_id_high`, `trace_id`, `id`) COMMENT 'for joining with zipkin_annotations';
ALTER TABLE zipkin_spans ADD INDEX(`trace_id_high`, `trace_id`) COMMENT 'for getTracesByIds';
ALTER TABLE zipkin_spans ADD INDEX(`name`) COMMENT 'for getTraces and getSpanNames';
ALTER TABLE zipkin_spans ADD INDEX(`start_ts`) COMMENT 'for getTraces ordering and range';
 
CREATE TABLE IF NOT EXISTS zipkin_annotations (
  `trace_id_high` BIGINT NOT NULL DEFAULT 0 COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit',
  `trace_id` BIGINT NOT NULL COMMENT 'coincides with zipkin_spans.trace_id',
  `span_id` BIGINT NOT NULL COMMENT 'coincides with zipkin_spans.id',
  `a_key` VARCHAR(255) NOT NULL COMMENT 'BinaryAnnotation.key or Annotation.value if type == -1',
  `a_value` BLOB COMMENT 'BinaryAnnotation.value(), which must be smaller than 64KB',
  `a_type` INT NOT NULL COMMENT 'BinaryAnnotation.type() or -1 if Annotation',
  `a_timestamp` BIGINT COMMENT 'Used to implement TTL; Annotation.timestamp or zipkin_spans.timestamp',
  `endpoint_ipv4` INT COMMENT 'Null when Binary/Annotation.endpoint is null',
  `endpoint_ipv6` BINARY(16) COMMENT 'Null when Binary/Annotation.endpoint is null, or no IPv6 address',
  `endpoint_port` SMALLINT COMMENT 'Null when Binary/Annotation.endpoint is null',
  `endpoint_service_name` VARCHAR(255) COMMENT 'Null when Binary/Annotation.endpoint is null'
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;
 
ALTER TABLE zipkin_annotations ADD UNIQUE KEY(`trace_id_high`, `trace_id`, `span_id`, `a_key`, `a_timestamp`) COMMENT 'Ignore insert on duplicate';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`, `span_id`) COMMENT 'for joining with zipkin_spans';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`) COMMENT 'for getTraces/ByIds';
ALTER TABLE zipkin_annotations ADD INDEX(`endpoint_service_name`) COMMENT 'for getTraces and getServiceNames';
ALTER TABLE zipkin_annotations ADD INDEX(`a_type`) COMMENT 'for getTraces';
ALTER TABLE zipkin_annotations ADD INDEX(`a_key`) COMMENT 'for getTraces';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id`, `span_id`, `a_key`) COMMENT 'for dependencies job';
 
CREATE TABLE IF NOT EXISTS zipkin_dependencies (
  `day` DATE NOT NULL,
  `parent` VARCHAR(255) NOT NULL,
  `child` VARCHAR(255) NOT NULL,
  `call_count` BIGINT,
  `error_count` BIGINT
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;
 
ALTER TABLE zipkin_dependencies ADD UNIQUE KEY(`day`, `parent`, `child`);

@EnableZipkinStreamServer也使用@EnableZipkinServer進行注釋,因此該過程還將公開標準的Zipkin服務(wù)器端點,以便通過HTTP收集跨度,以及在Zipkin Web UI中進行查詢。

4.Zipkin Stream Span消費者

重要:建議使用Zipkin對基于消息的跨度發(fā)送的本機支持。 從Edgware版本開始,不推薦使用Zipkin Stream服務(wù)器。 在Finchley發(fā)布中,它已被刪除。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容