一、工作环境
操作系统:Ubuntu 16.04
java环境:JDK 1.8
SpringBoot版本:1.5.13
SpringCloud版本:Edgware.SR3
二、项目配置
1. zipkin Server
pom.xml
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-server</artifactId>
</dependency>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-ui</artifactId>
<scope>runtime</scope>
</dependency>
application.yml
server:
port: 9411
ZipkinApplication.java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import zipkin.server.EnableZipkinServer;
@SpringBootApplication
@EnableZipkinServer
public class ZipkinApplication {
public static void main(String[] args) {
SpringApplication.run(ZipkinApplication.class, args);
}
}
2. zipkin client
pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
application.yml
spring:
zipkin:
base-url: http://zipkin-server:9411 //zipkin server的地址
sleuth:
sampler:
percentage: 0.1 //监测比例,默认为0.1,设置为1则为每次http动作都监控,但是对性能会有影响
细心的小伙伴可能发现了zipkin-client除了配置文件并没有对项目文件作任何修改,这是因为zipkin的工作原理是一旦监测到feign或者RestTemplate调用api接口就会自动将当前项目的本次http操作上传到配置文件里的zipkin server中。
因为每个项目的zipkin只能监控当前项目,而一次http会话中必定会有request和response,那么两个项目都需要作为zipkin client添加依赖。
三、测试
用postman多访问几次zipkin client的url,防止未监控到数据(我这里被坑惨了。。一直都以为是配置错误导致没数据,警醒后面的小伙伴)
获取到http数据!
四、参考
https://yq.aliyun.com/articles/60165
https://yq.aliyun.com/articles/78128
http://www.cnblogs.com/tietazhan/p/6873784.html
五、不定期更新
1. zipkin使用mysql进行持久化
默认情况下zipkin将数据保存在内存中(zipkin.storage.type=mem),一旦重启服务数据全部丢失,不适合生产环境
pom添加依赖
<!--保存到数据库需要如下依赖-->
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-storage-mysql</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
application.yml添加数据库相关配置
zipkin:
storage:
type: mysql
spring:
datasource:
url: jdbc:mysql://${MYSQL_HOST}:${MYSQL_TCP_PORT}/${MYSQL_DB}?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false
username: ${MYSQL_USERNAME}
password: ${MYSQL_PASSWORD}
driver-class-name: com.mysql.jdbc.Driver
环境变量请根据不同情况自行设置,除了数据库用户名和密码外都有默认配置(用户名和密码默认为空),默认配置如下:
host: ${MYSQL_HOST:localhost} // 数据库IP
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} // 数据库是否使用ssl连接
zipkin.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,
`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`);
微服务启动文件添加如下Bean
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.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();
}
}
注:网上的教程里引入的DataSource是javax.sql.DataSource,但是我引入这个包出现了Could not autowire. There is more than one bean of 'DataSource' type的错误,所以我换成了org.apache.tomcat.jdbc.pool.DataSource,目前没有出现问题。如果有小伙伴出现了异常后果欢迎留言讨论 ╮(╯▽╰)╭
小白所学尚浅,文章内容是根据参考+实践理解所得,如果有错误的地方欢迎指正!