Spring Cloud Sleuth與Zipkin配合使用

        Zipkin是Twitter開源的分佈式跟蹤系統,基於Dapper的論文設計而來。它的主要功能是收集系統的時序數據,從而追蹤微服務架構的系統延時等問題。Zipkin還提供了一個非常友好的界面,來幫助分析追蹤數據。

Zipkin服務

下載安裝與運行

進入 Zipkin 官網:https://zipkin.io/pages/quickstart.html

官方提供了一鍵腳本,分別執行以下兩個命令對 Zipkin 進行下載安裝和運行。

curl -sSL https://zipkin.io/quickstart.sh | bash -s
java -jar zipkin.jar

zipkin.jar中可配置的yaml文件配置參數

zipkin:
  self-tracing:
    # Set to true to enable self-tracing.
    enabled: ${SELF_TRACING_ENABLED:false}
    # percentage to self-traces to retain
    sample-rate: ${SELF_TRACING_SAMPLE_RATE:1.0}
    # Timeout in seconds to flush self-tracing data to storage.
    message-timeout: ${SELF_TRACING_FLUSH_INTERVAL:1}
  collector:
    # percentage to traces to retain
    sample-rate: ${COLLECTOR_SAMPLE_RATE:1.0}
    http:
      # Set to false to disable creation of spans via HTTP collector API
      enabled: ${HTTP_COLLECTOR_ENABLED:true}
    kafka:
      # ZooKeeper host string, comma-separated host:port value.
      zookeeper: ${KAFKA_ZOOKEEPER:}
      # Name of topic to poll for spans
      topic: ${KAFKA_TOPIC:zipkin}
      # Consumer group this process is consuming on behalf of.
      group-id: ${KAFKA_GROUP_ID:zipkin}
      # Count of consumer threads consuming the topic
      streams: ${KAFKA_STREAMS:1}
      # Maximum size of a message containing spans in bytes
      max-message-size: ${KAFKA_MAX_MESSAGE_SIZE:1048576}
    rabbitmq:
      # RabbitMQ server address list (comma-separated list of host:port)
      addresses: ${RABBIT_ADDRESSES:}
      concurrency: ${RABBIT_CONCURRENCY:1}
      # TCP connection timeout in milliseconds
      connection-timeout: ${RABBIT_CONNECTION_TIMEOUT:60000}
      password: ${RABBIT_PASSWORD:guest}
      queue: ${RABBIT_QUEUE:zipkin}
      username: ${RABBIT_USER:guest}
      virtual-host: ${RABBIT_VIRTUAL_HOST:/}
      useSsl: ${RABBIT_USE_SSL:false}
      uri: ${RABBIT_URI:}
  query:
    enabled: ${QUERY_ENABLED:true}
    # 1 day in millis
    lookback: ${QUERY_LOOKBACK:86400000}
    # The Cache-Control max-age (seconds) for /api/v1/services and /api/v1/spans
    names-max-age: 300
    # CORS allowed-origins.
    allowed-origins: "*"
  storage:
    strict-trace-id: ${STRICT_TRACE_ID:true}
    search-enabled: ${SEARCH_ENABLED:true}
    type: ${STORAGE_TYPE:mem}
    mem:
      # Maximum number of spans to keep in memory.  When exceeded, oldest traces (and their spans) will be purged.
      # A safe estimate is 1K of memory per span (each span with 2 annotations + 1 binary annotation), plus
      # 100 MB for a safety buffer.  You'll need to verify in your own environment.
      # Experimentally, it works with: max-spans of 500000 with JRE argument -Xmx600m.
      max-spans: 500000
    cassandra:
      # Comma separated list of host addresses part of Cassandra cluster. Ports default to 9042 but you can also specify a custom port with 'host:port'.
      contact-points: ${CASSANDRA_CONTACT_POINTS:localhost}
      # Name of the datacenter that will be considered "local" for latency load balancing. When unset, load-balancing is round-robin.
      local-dc: ${CASSANDRA_LOCAL_DC:}
      # Will throw an exception on startup if authentication fails.
      username: ${CASSANDRA_USERNAME:}
      password: ${CASSANDRA_PASSWORD:}
      keyspace: ${CASSANDRA_KEYSPACE:zipkin}
      # Max pooled connections per datacenter-local host.
      max-connections: ${CASSANDRA_MAX_CONNECTIONS:8}
      # Ensuring that schema exists, if enabled tries to execute script /zipkin-cassandra-core/resources/cassandra-schema-cql3.txt.
      ensure-schema: ${CASSANDRA_ENSURE_SCHEMA:true}
      # 7 days in seconds
      span-ttl: ${CASSANDRA_SPAN_TTL:604800}
      # 3 days in seconds
      index-ttl: ${CASSANDRA_INDEX_TTL:259200}
      # the maximum trace index metadata entries to cache
      index-cache-max: ${CASSANDRA_INDEX_CACHE_MAX:100000}
      # how long to cache index metadata about a trace. 1 minute in seconds
      index-cache-ttl: ${CASSANDRA_INDEX_CACHE_TTL:60}
      # how many more index rows to fetch than the user-supplied query limit
      index-fetch-multiplier: ${CASSANDRA_INDEX_FETCH_MULTIPLIER:3}
      # Using ssl for connection, rely on Keystore
      use-ssl: ${CASSANDRA_USE_SSL:false}
    cassandra3:
      # Comma separated list of host addresses part of Cassandra cluster. Ports default to 9042 but you can also specify a custom port with 'host:port'.
      contact-points: ${CASSANDRA_CONTACT_POINTS:localhost}
      # Name of the datacenter that will be considered "local" for latency load balancing. When unset, load-balancing is round-robin.
      local-dc: ${CASSANDRA_LOCAL_DC:}
      # Will throw an exception on startup if authentication fails.
      username: ${CASSANDRA_USERNAME:}
      password: ${CASSANDRA_PASSWORD:}
      keyspace: ${CASSANDRA_KEYSPACE:zipkin2}
      # Max pooled connections per datacenter-local host.
      max-connections: ${CASSANDRA_MAX_CONNECTIONS:8}
      # Ensuring that schema exists, if enabled tries to execute script /zipkin2-schema.cql
      ensure-schema: ${CASSANDRA_ENSURE_SCHEMA:true}
      # how many more index rows to fetch than the user-supplied query limit
      index-fetch-multiplier: ${CASSANDRA_INDEX_FETCH_MULTIPLIER:3}
      # Using ssl for connection, rely on Keystore
      use-ssl: ${CASSANDRA_USE_SSL:false}
    elasticsearch:
      # host is left unset intentionally, to defer the decision
      hosts: ${ES_HOSTS:}
      pipeline: ${ES_PIPELINE:}
      max-requests: ${ES_MAX_REQUESTS:64}
      timeout: ${ES_TIMEOUT:10000}
      aws:
        domain: ${ES_AWS_DOMAIN:}
        region: ${ES_AWS_REGION:}
      index: ${ES_INDEX:zipkin}
      date-separator: ${ES_DATE_SEPARATOR:-}
      index-shards: ${ES_INDEX_SHARDS:5}
      index-replicas: ${ES_INDEX_REPLICAS:1}
      username: ${ES_USERNAME:}
      password: ${ES_PASSWORD:}
      http-logging: ${ES_HTTP_LOGGING:}
      legacy-reads-enabled: ${ES_LEGACY_READS_ENABLED:true}
    mysql:
      host: ${MYSQL_HOST:localhost}
      port: ${MYSQL_TCP_PORT:3306}
      username: ${MYSQL_USER:}
      password: ${MYSQL_PASS:}
      db: ${MYSQL_DB:zipkin}
      max-active: ${MYSQL_MAX_CONNECTIONS:10}
      use-ssl: ${MYSQL_USE_SSL:false}
  ui:
    enabled: ${QUERY_ENABLED:true}
    ## Values below here are mapped to ZipkinUiProperties, served as /config.json
    # Default limit for Find Traces
    query-limit: 10
    # The value here becomes a label in the top-right corner
    environment:
    # Default duration to look back when finding traces.
    # Affects the "Start time" element in the UI. 1 hour in millis
    default-lookback: 3600000
    # When false, disables the "find a trace" screen
    search-enabled: ${SEARCH_ENABLED:true}
    # Which sites this Zipkin UI covers. Regex syntax. (e.g. http:\/\/example.com\/.*)
    # Multiple sites can be specified, e.g.
    # - .*example1.com
    # - .*example2.com
    # Default is "match all websites"
    instrumented: .*
    # URL placed into the <base> tag in the HTML
    base-path: /zipkin/
server:
  port: ${QUERY_PORT:9411}
  use-forward-headers: true
  compression:
    enabled: true
    # compresses any response over min-response-size (default is 2KiB)
    # Includes dynamic json content and large static assets from zipkin-ui
    mime-types: application/json,application/javascript,text/css,image/svg
spring:
  mvc:
    favicon:
      # zipkin has its own favicon
      enabled: false
  autoconfigure:
    exclude:
      # otherwise we might initialize even when not needed (ex when storage type is cassandra)
      - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
info:
  zipkin:
    version: "2.7.1"
logging:
  pattern:
    level: "%clr(%5p) %clr([%X{traceId}/%X{spanId}]){yellow}"
  level:
    # Silence Invalid method name: '__can__finagle__trace__v3__'
    com.facebook.swift.service.ThriftServiceProcessor: 'OFF'
#     # investigate /api/v1/dependencies or /api/v2/dependencies
#     zipkin2.internal.DependencyLinker: 'DEBUG'
#     # log cassandra queries (DEBUG is without values)
#     com.datastax.driver.core.QueryLogger: 'TRACE'
#     # log cassandra trace propagation
#     com.datastax.driver.core.Message: 'TRACE'
#     # log reason behind http collector dropped messages
#     zipkin.server.ZipkinHttpCollector: 'DEBUG'
#     zipkin.collector.kafka.KafkaCollector: 'DEBUG'
#     zipkin.collector.kafka10.KafkaCollector: 'DEBUG'
#     zipkin.collector.rabbitmq.RabbitMQCollector: 'DEBUG'
#     zipkin.collector.scribe.ScribeCollector: 'DEBUG'
management:
  security:
    # do not lock-down metrics by default
    # https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-1.5-Release-Notes#actuator-security
    enabled: false

配置參數通過RabbitMQ來接收sleuth數據

nohup java -jar zipkin.jar --zipkin.collector.rabbitmq.addresses=xx.55.41.xx --zipkin.collector.rabbitmq.username=rm_admin --zipkin.collector.rabbitmq.password=123456 --zipkin.collector.http.enabled=false --server.port=8677 > zipkin_8677.log 2>&1 &

啓動成功後,我們看RabbitMQ的管理界面,可以看到有一個zipkin的隊列,如下圖

改造Zipkin客戶端(服務提供者、服務消費者)

添加pom.xml依賴

    <!-- Only Sleuth (log correlation) -->
    <!-- 方式一、只是用sleuth作爲日誌 -->
    <!-- spring-cloud-starter-zipkin 會自動配置該依賴 -->
    <!-- 
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-sleuth</artifactId>
    </dependency>
    -->
    <!-- sleuth-stream  deprecated and incompatible with these destinations -->
    <!--
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-sleuth-stream</artifactId>
    </dependency>
    -->
     
    <!-- zipkin  Sleuth with Zipkin via HTTP -->
    <!-- 方式二、Sleuth和Zipkin通過HTTP方式直接傳輸數據 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-zipkin</artifactId>
    </dependency>

    <!-- 方式三、Sleuth和Zipkin通過消息中間件傳輸數據,需要加上方式二的依賴-->
    <!-- stream-rabbit = spring-cloud-stream + spring-cloud-stream-binder-rabbit -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
    </dependency>

改造yaml文件

#================rabbitmq====================    
spring.rabbitmq:
  host: 192.168.1.243
  virtual-host: /
  #與web訪問端口15672不一樣
  port: 5672
  username: rm_admin
  password: 12345678
#=================zipkin=====================
spring.zipkin:
  #base-url: http://localhost:8677
  sender:
   type: rabbit
  enable: true
#=================sleuth=====================
spring.sleuth:
  web:
    client:
      enabled: true
  sampler:
    #設置採樣比例,1.0表示100%,即全部都要;默認是0.1
    probability: 1.0

服務消費方和服務提供者的sleuth日誌數據

通過一次服務調用,看下消費者和提供者的日誌數據信息,可以看到

traceId是e1411d8dd0fac3fa

spanId是adfc9d7125aad0d1、f89ea2c518047551

服務消費者

2020-04-07 21:09:45.534 DEBUG [ms-provider-user,e1411d8dd0fac3fa,adfc9d7125aad0d1,true] 30464 --- [nsumer-order-10] c.s.i.w.c.f.TraceLoadBalancerFeignClient : Before send
2020-04-07 21:09:45.536 DEBUG [ms-provider-user,e1411d8dd0fac3fa,adfc9d7125aad0d1,true] 30464 --- [nsumer-order-10] o.s.c.s.i.w.c.f.LazyTracingFeignClient   : Sending a request via tracing feign client [org.springframework.cloud.sleuth.instrument.web.client.feign.TracingFeignClient@5a9af357] and the delegate [feign.Client$Default@2aba028e]
2020-04-07 21:09:45.537 DEBUG [ms-provider-user,e1411d8dd0fac3fa,adfc9d7125aad0d1,true] 30464 --- [nsumer-order-10] o.s.c.s.i.w.c.feign.TracingFeignClient   : Handled send of RealSpan(e1411d8dd0fac3fa/f89ea2c518047551)
2020-04-07 21:09:45.579 DEBUG [ms-provider-user,e1411d8dd0fac3fa,adfc9d7125aad0d1,true] 30464 --- [nsumer-order-10] o.s.c.s.i.w.c.feign.TracingFeignClient   : Handled receive of RealSpan(e1411d8dd0fac3fa/f89ea2c518047551)
2020-04-07 21:09:45.579 DEBUG [ms-provider-user,e1411d8dd0fac3fa,adfc9d7125aad0d1,true] 30464 --- [nsumer-order-10] c.s.i.w.c.f.TraceLoadBalancerFeignClient : After receive

服務提供者

2020-04-07 21:09:45.543 DEBUG [ms-consumer-order,e1411d8dd0fac3fa,f89ea2c518047551,true] 22724 --- [nio-9080-exec-4] c.m.c.b.d.RoleEntityMapper.getAllRoles   : ==>  Preparing: Select * from t_role 
2020-04-07 21:09:45.544 DEBUG [ms-consumer-order,e1411d8dd0fac3fa,f89ea2c518047551,true] 22724 --- [nio-9080-exec-4] c.m.c.b.d.RoleEntityMapper.getAllRoles   : ==> Parameters: 
2020-04-07 21:09:45.576 DEBUG [ms-consumer-order,e1411d8dd0fac3fa,f89ea2c518047551,true] 22724 --- [nio-9080-exec-4] c.m.c.b.d.RoleEntityMapper.getAllRoles   : <==      Total: 1

通過Zipkin觀察收集的數據

我們讓兩個微服務進行了互相的調用MS-CONSUMER-ORDER、MS-PROVIDER-USER

Zipkin數據存儲

ZipkinServer支持多種後端存儲,例如MySQL、Elasticsearch、Cassandra等,可以根據自己的情況使用。

總體架構圖

 

參考官方文檔:https://cloud.spring.io/spring-cloud-static/Greenwich.SR5/multi/multi__introduction.html#_sleuth_with_zipkin_via_http 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章