springCloud中使用zipkin+(rabbitmq、activemq)+(elasticsearch、mysql)实现链路追踪

一、前言

1、部署之前首先要准备zipkin、rabbitmqactivemqelasticsearch、mysql等部署环境。

zipkin+rabbitmq+elasticsearch/mysql

zipkin+activemq+elasticsearch/mysql

2、本篇文章只是叙述zipkin的部署和使用方法,其他组件可自行部署。

二、zipkin的服务端搭建

1、首先到此地址https://dl.bintray.com/openzipkin/maven/io/zipkin/java/zipkin-server/下载zipkin.jar包

下载完成后可上传到指定目录

或者使用以下命令直接安装

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

java -jar zipkin.jar

 2、安装完成后启动

1、使用rabbitmq+elasticsearch的启动方式

java -jar zipkin.jar --zipkin.collector.rabbitmq.addresses=62.234.66.186 --zipkin.collector.rabbitmq.username=root --zipkin.collector.rabbitmq.password=123456 --zipkin.storage.type=elasticsearch --zipkin.storage.elasticsearch.host=http://62.234.66.186:9200 --zipkin.storage.elasticsearch.http-logging=BASIC

2、使用rabbitmq+mysql启动方式

java -jar zipkin.jar --zipkin.collector.rabbitmq.addresses=62.234.66.186 --zipkin.collector.rabbitmq.username=root --zipkin.collector.rabbitmq.password=123456 --zipkin.storage.type=mysql --zipkin.storage.mysql.host=62.234.66.186 --zipkin.storage.mysql.port=3306 --zipkin.storage.mysql.username=root --zipkin.storage.mysql.password=root --zipkin.storage.mysql.db=psych

3、使用activemq+mysql启动方式

java -jar zipkin.jar --zipkin.collector.activemq.url=tcp://62.234.66.186:61616 --zipkin.collector.activemq.username=admin --zipkin.collector.activemq.password=admin --zipkin.storage.type=mysql --zipkin.storage.mysql.host=62.234.66.186 --zipkin.storage.mysql.port=3306 --zipkin.storage.mysql.username=root --zipkin.storage.mysql.password=root --zipkin.storage.mysql.db=psych

4、使用activemq+elasticsearch方式雷同,只需要将数据源改为elasticsearch即可

 

3、官方文件配置中心 

https://github.com/openzipkin/zipkin/blob/master/zipkin-server/src/main/resources/zipkin-server-shared.yml

zipkin:
  self-tracing:
  # Set to true to enable self-tracing.
  enabled: ${SELF_TRACING_ENABLED:false}
  # percentage of self-traces to retain. If set to a value other than 1.0, traces-per-second will
  # not be used.
  sample-rate: ${SELF_TRACING_SAMPLE_RATE:1.0}
  # Number of traces per second to retain. sample-rate must be set to 1.0 to use this value. If
  # set to 0, an unlimited number of traces per second will be retained.
  traces-per-second: ${SELF_TRACING_TRACES_PER_SECOND:1}
  # 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}
  activemq:
  enabled: ${COLLECTOR_ACTIVEMQ_ENABLED:true}
  # ActiveMQ broker url. Ex. tcp://localhost:61616 or failover:(tcp://localhost:61616,tcp://remotehost:61616)
  url: ${ACTIVEMQ_URL:}
  # Queue from which to collect span messages.
  queue: ${ACTIVEMQ_QUEUE:zipkin}
  # Number of concurrent span consumers.
  concurrency: ${ACTIVEMQ_CONCURRENCY:1}
  # Optional username to connect to the broker
  username: ${ACTIVEMQ_USERNAME:}
  # Optional password to connect to the broker
  password: ${ACTIVEMQ_PASSWORD:}
  http:
  # Set to false to disable creation of spans via HTTP collector API
  enabled: ${COLLECTOR_HTTP_ENABLED:${HTTP_COLLECTOR_ENABLED:true}}
  grpc:
  # Set to true to enable the GRPC collector
  enabled: ${COLLECTOR_GRPC_ENABLED:false}
  kafka:
  enabled: ${COLLECTOR_KAFKA_ENABLED:true}
  # Kafka bootstrap broker list, comma-separated host:port values. Setting this activates the
  # Kafka 0.10+ collector.
  bootstrap-servers: ${KAFKA_BOOTSTRAP_SERVERS:}
  # 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}
  rabbitmq:
  enabled: ${COLLECTOR_RABBITMQ_ENABLED:true}
  # 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:}
  scribe:
  enabled: ${COLLECTOR_SCRIBE_ENABLED:${SCRIBE_ENABLED:false}}
  category: ${SCRIBE_CATEGORY:zipkin}
  port: ${COLLECTOR_PORT:9410}
  query:
  enabled: ${QUERY_ENABLED:true}
  # Timeout for requests to the query API
  timeout: ${QUERY_TIMEOUT:11s}
  # 1 day in millis
  lookback: ${QUERY_LOOKBACK:86400000}
  # The Cache-Control max-age (seconds) for /api/v2/services, /api/v2/remoteServices and /api/v2/spans
  names-max-age: 300
  # CORS allowed-origins.
  allowed-origins: "*"
   
  # Internal properties that end users should never try to use
  internal:
  actuator:
  enabled: true
  # auto-configuration to include when ArmeriaSpringActuatorAutoConfiguration is present.
  # Note: These are still subject to endpoint conditions. The list must be checked for drift
  # upgrading Spring Boot.
  include:
  - org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration
  - org.springframework.boot.actuate.autoconfigure.condition.ConditionsReportEndpointAutoConfiguration
  - org.springframework.boot.actuate.autoconfigure.context.properties.ConfigurationPropertiesReportEndpointAutoConfiguration
  - org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration
  - org.springframework.boot.actuate.autoconfigure.env.EnvironmentEndpointAutoConfiguration
  - org.springframework.boot.actuate.autoconfigure.management.HeapDumpWebEndpointAutoConfiguration
  - org.springframework.boot.actuate.autoconfigure.logging.LoggersEndpointAutoConfiguration
  - org.springframework.boot.actuate.autoconfigure.management.ThreadDumpEndpointAutoConfiguration
   
  storage:
  strict-trace-id: ${STRICT_TRACE_ID:true}
  search-enabled: ${SEARCH_ENABLED:true}
  autocomplete-keys: ${AUTOCOMPLETE_KEYS:}
  autocomplete-ttl: ${AUTOCOMPLETE_TTL:3600000}
  autocomplete-cardinality: 20000
  type: ${STORAGE_TYPE:mem}
  throttle:
  enabled: ${STORAGE_THROTTLE_ENABLED:false}
  min-concurrency: ${STORAGE_THROTTLE_MIN_CONCURRENCY:10}
  max-concurrency: ${STORAGE_THROTTLE_MAX_CONCURRENCY:200}
  max-queue-size: ${STORAGE_THROTTLE_MAX_QUEUE_SIZE:1000}
  mem:
  # Maximum number of spans to keep in memory. When exceeded, oldest traces (and their spans) will be purged.
  max-spans: ${MEM_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.cql.
  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:}
  timeout: ${ES_TIMEOUT:10000}
  index: ${ES_INDEX:zipkin}
  ensure-templates: ${ES_ENSURE_TEMPLATES:true}
  date-separator: ${ES_DATE_SEPARATOR:-}
  index-shards: ${ES_INDEX_SHARDS:5}
  index-replicas: ${ES_INDEX_REPLICAS:1}
  username: ${ES_USERNAME:}
  password: ${ES_PASSWORD:}
  credentials-file: ${ES_CREDENTIALS_FILE:}
  credentials-refresh-interval: ${ES_CREDENTIALS_REFRESH_INTERVAL:5}
  http-logging: ${ES_HTTP_LOGGING:}
  health-check:
  enabled: ${ES_HEALTH_CHECK_ENABLED:true}
  interval: ${ES_HEALTH_CHECK_INTERVAL:3s}
  mysql:
  jdbc-url: ${MYSQL_JDBC_URL:}
  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. 15 minutes in millis
  default-lookback: 900000
  # When false, disables the "Discover" 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
   
  # We are using Armeria instead of Tomcat. Have it inherit the default configuration from Spring
  spring.main.web-application-type: none
  # These defaults are not used directly. They are used via armeria namespacing
  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
  min-response-size: 2048
   
  armeria:
  ports:
  - port: ${server.port}
  protocols:
  - http
  compression:
  enabled: ${server.compression.enabled}
  mime-types: ${server.compression.mime-types}
  min-response-size: ${server.compression.min-response-size}
  gracefulShutdownQuietPeriodMillis: -1
  gracefulShutdownTimeoutMillis: -1
   
  spring:
  jmx:
  # reduce startup time by excluding unexposed JMX service
  enabled: false
  mvc:
  favicon:
  # zipkin has its own favicon
  enabled: false
  autoconfigure:
  # NOTE: These exclusions can drift between Spring Boot minor versions. Audit accordingly.
  # Ex. curl -s localhost:9411/actuator/beans|jq '.contexts.application.beans|keys_unsorted[]'|sort
  exclude:
  # JMX is disabled
  - org.springframework.boot.actuate.autoconfigure.endpoint.jmx.JmxEndpointAutoConfiguration
  # /health and /actuator/health served directly by Armeria
  - org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration
  - org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration
  # /info and /actuator/info served directly by Armeria (content is /info.json)
  - org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration
  - org.springframework.boot.actuate.autoconfigure.info.InfoContributorAutoConfiguration
  # /prometheus and /actuator/prometheus are served directly by Armeria
  - org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus.PrometheusMetricsExportAutoConfiguration
  # Remove unused auto-configuration
  - org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration
  - org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration
  - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
  - org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration
  - org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration
  - org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration
  - org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration
  logging:
  pattern:
  level: "%clr(%5p) %clr([%X{traceId}/%X{spanId}]){yellow}"
  level:
  # Silence ResponseTimeoutException in the Armeria framework since we log it anyways in HTTP
  # logging when enabled. https://github.com/line/armeria/issues/2000
  com.linecorp.armeria.client.HttpResponseDecoder: 'OFF'
  com.linecorp.armeria.common.Flags: 'OFF'
  com.linecorp.armeria.server.docs.DocStringExtractor: 'OFF'
  # # investigate /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
  # zipkin2.server.ZipkinHttpCollector: 'DEBUG'
  # zipkin2.collector.kafka.KafkaCollector: 'DEBUG'
  # zipkin2.collector.rabbitmq.RabbitMQCollector: 'DEBUG'
  # zipkin2.collector.scribe.ScribeCollector: 'DEBUG'
  management:
  endpoints:
  web:
  exposure:
  include: '*'
  # Below are served directly without actuator.
  endpoint:
  health:
  enabled: false
  prometheus:
  enabled: false
  info:
  enabled: false
  # Disabling auto time http requests since it is added in ZipkinPrometheusMetricsConfiguration
  # In Zipkin we use different naming for the http requests duration
  metrics:
  web:
  server:
  auto-time-requests: false

 5、如果使用mysql则需要创建以下几张表,,官网地址

https://github.com/openzipkin/zipkin/blob/master/zipkin-storage/mysql-v1/src/main/resources/mysql.sql

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,
  `remote_service_name` VARCHAR(255),
  `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',
  PRIMARY KEY (`trace_id_high`, `trace_id`, `id`)
  ) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;
   
  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(`remote_service_name`) COMMENT 'for getTraces and getRemoteServiceNames';
  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 and autocomplete values';
  ALTER TABLE zipkin_annotations ADD INDEX(`a_key`) COMMENT 'for getTraces and autocomplete values';
  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,
  PRIMARY KEY (`day`, `parent`, `child`)
  ) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;

三、微服务客户端引入zipkin

1、首先在自己新建微服务项目中引入依赖

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
 </dependency>

2、在pom加入如下配置

springCloud中使用zipkin+(rabbitmq、activemq)+(elasticsearch、mysql)实现链路追踪

 

 3、到此集成就已经完成,如下图

springCloud中使用zipkin+(rabbitmq、activemq)+(elasticsearch、mysql)实现链路追踪

到此zipkin链路追踪部署成功