SpringCloud:Zipkin链路追踪,并将数据写入mysql
1.zipkin server
1.1.新建Springboot项目,zinkin
1.2.添加依赖
<dependency> <groupId>io.zipkin.java</groupId> <artifactId>zipkin-server</artifactId> </dependency> <dependency> <groupId>io.zipkin.java</groupId> <artifactId>zipkin-autoconfigure-ui</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>io.zipkin.java</groupId> <artifactId>zipkin-autoconfigure-storage-mysql</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>io.zipkin.java</groupId> <artifactId>zipkin-storage-mysql</artifactId> <version>2.4.9</version> </dependency>
1.3.修改配置文件
zipkin: storage: type: mysql spring: datasource: schema: classpath*:sql/mysql.sql url: jdbc:mysql://127.0.0.1:3306/altair_tmp?useUnicode=true&characterEncoding=utf8&autoReconnect=true username: root password: 123456 # Switch this on to create the schema on startup: # initialize: true # continueOnError: true sleuth: enabled: false server: port: 9944 eureka: client: service-url: defaultZone: http://th-blog.cn:7000/eureka/
1.4.主启动类
package com.chinawayltd.altair.zipkin; import org.apache.tomcat.jdbc.pool.DataSource; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.context.annotation.Bean; import zipkin.server.internal.EnableZipkinServer; import zipkin.storage.mysql.MySQLStorage; @SpringBootApplication @EnableEurekaClient @EnableZipkinServer public class ZipkinApplication { public static void main(String[] args) { SpringApplication.run(ZipkinApplication.class, args); } @Bean public MySQLStorage mySQLStorage(DataSource datasource) { return MySQLStorage.builder().datasource(datasource).executor(Runnable::run).build(); } }
1.5.新建表
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'; CREATE TABLE IF NOT EXISTS zipkin_dependencies ( `day` DATE NOT NULL, `parent` VARCHAR(255) NOT NULL, `child` VARCHAR(255) NOT NULL, `call_count` BIGINT ) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci; ALTER TABLE zipkin_dependencies ADD UNIQUE KEY(`day`, `parent`, `child`);
2.zipkin client
2.1.添加依赖
<dependency> <groupId>io.zipkin.brave</groupId> <artifactId>brave-core</artifactId> </dependency> <dependency> <groupId>io.zipkin.brave</groupId> <artifactId>brave-http</artifactId> </dependency> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>3.8.1</version> <scope>compile</scope> </dependency> <dependency> <groupId>io.zipkin.brave</groupId> <artifactId>brave-spancollector-http</artifactId> </dependency> <dependency> <groupId>io.zipkin.brave</groupId> <artifactId>brave-okhttp</artifactId> </dependency> <dependency> <groupId>io.zipkin.brave</groupId> <artifactId>brave-web-servlet-filter</artifactId> </dependency> <dependency> <groupId>io.zipkin.brave</groupId> <artifactId>brave-mysql</artifactId> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> </dependency>
2.2.修改配置文件
com:
zipkin:
serviceName: altair-user-console-v1
url: http://localhost:9944
connectTimeout: 6000
readTimeout: 6000
flushInterval: 1
compressionEnabled: true
2.3.config
package com.chinawayltd.altair.user.console.config; import com.github.kristofa.brave.Brave; import com.github.kristofa.brave.EmptySpanCollectorMetricsHandler; import com.github.kristofa.brave.Sampler; import com.github.kristofa.brave.SpanCollector; import com.github.kristofa.brave.http.DefaultSpanNameProvider; import com.github.kristofa.brave.http.HttpSpanCollector; import com.github.kristofa.brave.mysql.MySQLStatementInterceptorManagementBean; import com.github.kristofa.brave.okhttp.BraveOkHttpRequestResponseInterceptor; import com.github.kristofa.brave.servlet.BraveServletFilter; import okhttp3.OkHttpClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * Created by liaokailin on 16/7/27. */ @Configuration public class ZipkinConfig { @Value("${com.zipkin.serviceName}") private String serviceName; @Value("${com.zipkin.url}") private String url; @Value("${com.zipkin.connectTimeout}") private int connectTimeout; @Value("${com.zipkin.readTimeout}") private int readTimeout; @Value("${com.zipkin.flushInterval}") private int flushInterval; @Value("${com.zipkin.compressionEnabled}") private boolean compressionEnabled; @Bean public SpanCollector spanCollector() { HttpSpanCollector.Config config = HttpSpanCollector.Config.builder().connectTimeout(connectTimeout).readTimeout(readTimeout) .compressionEnabled(compressionEnabled).flushInterval(flushInterval).build(); return HttpSpanCollector.create(url, config, new EmptySpanCollectorMetricsHandler()); } @Bean public Brave brave(SpanCollector spanCollector){ Brave.Builder builder = new Brave.Builder(serviceName); //指定state builder.spanCollector(spanCollector); builder.traceSampler(Sampler.ALWAYS_SAMPLE); Brave brave = builder.build(); return brave; } @Bean public BraveServletFilter braveServletFilter(Brave brave){ BraveServletFilter filter = new BraveServletFilter(brave.serverRequestInterceptor(),brave.serverResponseInterceptor(),new DefaultSpanNameProvider()); return filter; } @Bean public OkHttpClient okHttpClient(Brave brave){ OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(new BraveOkHttpRequestResponseInterceptor(brave.clientRequestInterceptor(), brave.clientResponseInterceptor(), new DefaultSpanNameProvider())) .build(); return client; } @Bean public MySQLStatementInterceptorManagementBean mySQLStatementInterceptorManagementBean(Brave brave) { return new MySQLStatementInterceptorManagementBean(brave.clientTracer()); } }
参考文档:https://blog.csdn.net/qq_37843943/article/details/80835437
https://my.oschina.net/u/136848/blog/1623460