Spring Cloud(七):链路追踪Sleuth-Zipkin与Mysql数据的持久化

来源:互联网 发布:网络 信息 平台 建设 编辑:程序博客网 时间:2024/05/24 01:08

一:回顾
上节我们了解到Spring Cloud Sleuth可以实现对服务的追踪,以及和Zipkin结合,可以可视化服务追踪界面和依赖等相关信息。遗憾的是数据不能持久化。

二:项目的构建
构建三个项目sleuth-stream-server,sleuth-stream-provider,sleuth-stream-consumer
前期准备:
下载rabbitMq,http://www.rabbitmq.com/
启动rabbit服务,
这里写图片描述

2.1:sleuth-stream-server构建
2.1.1:pom.xml

<parent>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-parent</artifactId>    <version>1.5.6.RELEASE</version>    <relativePath/> <!-- lookup parent from repository --></parent><properties>    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>    <java.version>1.8</java.version>    <spring-cloud.version>Dalston.SR2</spring-cloud.version></properties><dependencies>    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter</artifactId>    </dependency>    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-test</artifactId>        <scope>test</scope>    </dependency>    <!--此依赖会自动引入spring-cloud-sleuth-stream并且引入zipkin的依赖包-->    <dependency>        <groupId>org.springframework.cloud</groupId>        <artifactId>spring-cloud-sleuth-zipkin-stream</artifactId>    </dependency>    <dependency>        <groupId>org.springframework.cloud</groupId>        <artifactId>spring-cloud-starter-stream-rabbit</artifactId>    </dependency>    <dependency>        <groupId>io.zipkin.java</groupId>        <artifactId>zipkin-autoconfigure-ui</artifactId>        <scope>runtime</scope>    </dependency>    <!--保存到数据库需要如下依赖-->    <dependency>        <groupId>mysql</groupId>        <artifactId>mysql-connector-java</artifactId>    </dependency>    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-jdbc</artifactId>    </dependency></dependencies><dependencyManagement>    <dependencies>        <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-dependencies</artifactId>            <version>${spring-cloud.version}</version>            <type>pom</type>            <scope>import</scope>        </dependency>    </dependencies></dependencyManagement><build>    <plugins>        <plugin>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-maven-plugin</artifactId>        </plugin>    </plugins></build>

2.1.2:application.properties

server.port=9110spring.application.name=zipkin-stream-server#zipkin数据保存到数据库中需要进行如下配置#表示当前程序不使用sleuthspring.sleuth.enabled=false#表示zipkin数据存储方式是mysqlzipkin.storage.type=mysql#数据库脚本创建地址,当有多个是可使用[x]表示集合第几个元素spring.datasource.schema[0]=classpath:/mysql.sql#spring boot数据源配置    spring.datasource.url=jdbc:mysql://localhost:3306/sleuth_log?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=falsespring.datasource.username=rootspring.datasource.password=123456spring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.datasource.initialize=truespring.datasource.continue-on-error=true#rabbitmq配置spring.rabbitmq.host=localhostspring.rabbitmq.port=5672spring.rabbitmq.username=guestspring.rabbitmq.password=guest

2.1.3:在classPath目录下新建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,  `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`);

2.1.4:入口程序

@SpringBootApplication@EnableZipkinStreamServerpublic class SleuthStreamServerApplication {public static void main(String[] args) {    SpringApplication.run(SleuthStreamServerApplication.class, args);}@Beanpublic MySQLStorage mySQLStorage(DataSource datasource) {    return MySQLStorage.builder().datasource(datasource).executor(Runnable::run).build();    }}

3.1:sleuth-stream-provider
3.1.1:pom.xml

<parent>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-parent</artifactId>    <version>1.5.6.RELEASE</version>    <relativePath/> <!-- lookup parent from repository --></parent><properties>    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>    <java.version>1.8</java.version>    <spring-cloud.version>Dalston.SR2</spring-cloud.version></properties><dependencies>    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-web</artifactId>    </dependency>    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-test</artifactId>        <scope>test</scope>    </dependency>    <dependency>        <groupId>org.springframework.cloud</groupId>        <artifactId>spring-cloud-sleuth-zipkin-stream</artifactId>    </dependency>    <dependency>        <groupId>org.springframework.cloud</groupId>        <artifactId>spring-cloud-starter-stream-rabbit</artifactId>    </dependency>    <dependency>        <groupId>org.springframework.cloud</groupId>        <artifactId>spring-cloud-starter-sleuth</artifactId>    </dependency></dependencies><dependencyManagement>    <dependencies>        <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-dependencies</artifactId>            <version>${spring-cloud.version}</version>            <type>pom</type>            <scope>import</scope>        </dependency>    </dependencies></dependencyManagement><build>    <plugins>        <plugin>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-maven-plugin</artifactId>        </plugin>    </plugins></build>

3.1.2:application.yml

server:  port: 9111spring:  application:    name: sleuth-stream-provider #rabbitmq配置  rabbitmq:    host: localhost    username: guest    password: guest

3.1.3: 程序入口

@SpringBootApplicationpublic class SleuthStreamProviderApplication {public static void main(String[] args) {    SpringApplication.run(SleuthStreamProviderApplication.class, args);    }}

3.1.4:提供一个服务

@RestControllerpublic class SleuthProviderController {private static final Logger LOGGER = LoggerFactory.getLogger(SleuthProviderController.class);@GetMapping({"","/"})public String index(){    return "this is a spring-cloud sleuth provider!";}/** * 用来测试链路 * @return */@GetMapping("/index")public String providerIndex(){    LOGGER.info("<<<<<<<<<<<<<<<<trace sleuth demo provider is being called! >>>>>>>>>>>>>>>");    return "Hello dy_bom ,this is a spring-cloud sleuth provider!";        }}

4.1:sleuth-stream-consumer
4.1.1:pom.xml

 <parent>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-parent</artifactId>    <version>1.5.6.RELEASE</version>    <relativePath/> <!-- lookup parent from repository --></parent><properties>    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>    <java.version>1.8</java.version>    <spring-cloud.version>Dalston.SR2</spring-cloud.version></properties><dependencies>    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-web</artifactId>    </dependency>    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-test</artifactId>        <scope>test</scope>    </dependency>    <dependency>        <groupId>org.springframework.cloud</groupId>        <artifactId>spring-cloud-sleuth-zipkin-stream</artifactId>    </dependency>    <dependency>        <groupId>org.springframework.cloud</groupId>        <artifactId>spring-cloud-starter-stream-rabbit</artifactId>    </dependency>    <dependency>        <groupId>org.springframework.cloud</groupId>        <artifactId>spring-cloud-starter-sleuth</artifactId>    </dependency></dependencies><dependencyManagement>    <dependencies>        <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-dependencies</artifactId>            <version>${spring-cloud.version}</version>            <type>pom</type>            <scope>import</scope>        </dependency>    </dependencies></dependencyManagement><build>    <plugins>        <plugin>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-maven-plugin</artifactId>        </plugin>    </plugins></build>

4.1.2:application.yml

server:  port: 9112spring:  application:    name: sleuth-stream-consumer#rabbitmq配置  rabbitmq:    host: localhost    username: guest    password: guest

4.1.3:程序入口

@SpringBootApplicationpublic class SleuthStreamConsumerApplication {public static void main(String[] args) {    SpringApplication.run(SleuthStreamConsumerApplication.class, args);    }}

4.1.4:服务消费

@RestControllerpublic class SleuthConsumerController {private static final Logger LOGGER = LoggerFactory.getLogger(SleuthConsumerController.class);@Autowiredprivate RestTemplate restTemplate;@Beanpublic RestTemplate getRestTemplate(){    return new RestTemplate();}/** * 项目说明 * @return */@GetMapping({"/",""})public String index(){    return "this is spring-cloud-sleuth-consumer";}/** * 远程服务 * @return */@GetMapping( "/index")public Object sleuthProviderIndex() {    LOGGER.info("<<<<<<<<<<<<<<<<calling trace demo provider>>>>>>>>>>>>>>>");    String str =  restTemplate.getForObject("http://localhost:9111/index", String.class);    return str;    } }

说明,从上面的配置可以看出,我们客户端无须加入配置Server的地址。因为我们不是通过Http的Zipkin来收集数据。而是通过数据流Stream传输的。而且在这里我们没有配置它的手机采集率,即是默认的0.1。

三:项目的启动。
依次启动项目Server端,服务提供端,服务消费端。
多次访问:http://localhost:9112/index
这里写图片描述
看日志。解释一下:
红色部分分别表示服务名称,traceId,spanId,boolean(代表是否进入了ZipKin),由于我们没设置采集率所以,你会发现很多false。
查看数据库是否入库了:
这里写图片描述
查看zipKin管理页面,查看追踪信息
这里写图片描述

可以看出描述的很详细。

四:重启Server端
重启Server,查看zipKin管理页面,查看追踪信息是否有历史数据

代码地址:https://github.com/rubenYuan/Spring-Cloud-Samples
PPT:http://download.csdn.net/download/ruben95001/9974839

完!

阅读全文
2 0
原创粉丝点击