一、什么是sleuth
1.微服务的现状?
微服务的现状
随着业务的发展,单体架构变为微服务架构,并且系统规模也变得越来越大,各微服务间的调用关系也变得越来越复杂。
多服务协同工作
在微服务的应用中,一个由客户端发起的请求在后端系统中会经过多个不同的微服务调用来协同产生最后的请求结果
复杂的调用链条容易出错
在复杂的微服务架构系统中,几乎每一个前端请求都会形成一个复杂的分布式服务调用链路,在每条链路中任何一个依赖服务出现延迟超时或者错误都有可能引起整个请求最后的失败
例如:
在微服务系统中,一个来自用户的请求,请求先达到前端A(如前端界面)然后通过远程调用,到达系统中间件B,C(负载均衡,网关等),最后达到后端服务D,E,后端经过一系列的业务逻辑计算最后将数据返回给用户,对于这样一个请求,经历了这么多个服务,怎么样将它的请求过程的数据记录下来呢?这就需要用到服务链路追踪
2.微服务跟踪解决了什么问题?
微服务跟踪(sleuth)其实是一个工具,它在整个分布式系统中能跟踪一个用户请求的过程(包括数据采集,数据传输,数据存储,数据分析,数据可视化),捕获这些跟踪数据,就能构建微服务的整个调用链的视图,这是调试和监控微服务的关键工具。
SpringCloudSleuth有4个特点
二、启动zipkin-server
Spring Boot 2.x 以后官网不推荐使用源码方式编译,推荐使用官网编译好的jar执行
下载jar包,地址 https://search.maven.org/remote_content?g=io.zipkin&a=zipkin-server&v=LATEST&c=exec
三种命令启动jar
http方式启动
java -jar zipkin-server-2.23.2-exec.jar
rabbitmq方式启动
java -jar zipkin-server-2.23.2-exec.jar --RABBIT_ADDRESSES=127.0.0.1:5672
elasticsearch + rabbitmq 方式启动
java -jar zipkin-server-2.23.2-exec.jar --STORAGE_TYPE=elasticsearch --ES_HOSTS=http://127.0.0.1:9200 --RABBIT_ADDRESSES=127.0.0.1:5672 --ES_USERNAME=elastic --ES_PASSWORD=123456
三、搭建项目
①搭建父pom文件
<properties>
<spring-boot.version>2.2.2.RELEASE</spring-boot.version>
<spring-cloud.version>Hoxton.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<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>
②搭建注册中心
本项目使用eureka注册中心,如何搭建注册中心本文章不再赘述
③搭建服务A和服务B(A调用B的关系)
a.服务A
pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>kim-sleuth-zipkin</artifactId>
<groupId>com.kim</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>kim-A</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- eureka -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- feign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.0</version>
</dependency>
<!-- 服务追踪 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<!-- 使用 Rabbit 连接方式启动才需要下面依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!-- 使用es存储链路追踪 -->
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-storage-elasticsearch-http</artifactId>
<version>2.8.4</version>
</dependency>
</dependencies>
</project>
application.yml文件
server:
port: 31001
#开发配置
###数据库配置
spring:
application:
name: kim-a
zipkin:
# base-url: http://127.0.0.1:9411
sender:
type: rabbit
sleuth:
sampler:
probability: 1.0 #跟踪信息收集采样比例,默认 0.1,为 1 即 100%,收集所有 注意之前的版本是 percentage 新版本中更换为 probability
# rate: 50 # 每秒速率,即每秒最多能跟踪的请求,rate 优先
#Sleuth 使用 Rabbitmq 来向 Zipkin 发送数据
rabbitmq:
host: 127.0.0.1
port: 5672
username: guest
password: guest
zipkin:
storage:
type: elasticsearch
elasticsearch:
hosts: http://127.0.0.1:9200
username: elastic
password: 123456
cluster: elasticsearch
index: zipkin
index-shards: 1
index-replicas: 1
eureka:
client:
register-with-eureka: true #表示注册到eureka
fetch-registry: true #是否从eurekaServer抓取已有的注册信息,集群必须设置为true才能配合ribbon使用负载均衡
service-url:
defaultZone: http://localhost:17001/eureka
# defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka #集群版
instance:
# instance-id: ${spring.application.name}:${random.int[40000,50000]}
instance-id: ${spring.application.name}
prefer-ip-address: true #访问路径可以显示ip
server: #关闭自我保护机制,保证不可用服务被及时剔除
enable-self-preservation: false
eviction-interval-timer-in-ms: 2000
logging:
level:
com:
codingapi:
txlcn: DEBUG
#开启Feign的熔断Fallback
feign:
hystrix:
enabled: true
#关闭Ribbon重试机制:
ribbon:
ConnectTimeout: 5000
ReadTimeout: 60000
MaxAutoRetries: 0
MaxAutoRetriesNextServer: 0
启动类
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableEurekaClient
@EnableFeignClients(basePackages = {"com.a.server.service.feign"})
@EnableDiscoveryClient
public class AserverApplication {
public static void main(String []args){
SpringApplication.run(AserverApplication.class,args);
}
}
controller层
@RestController
@RequestMapping("/a")
@Slf4j
public class AserverController {
@Resource
private BserverFeignService bserverFeignService;
@PostMapping("/server")
public String server(){
log.info("a服务正在被调用");
String server = bserverFeignService.server();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "ok";
}
}
service层
@FeignClient(value = "kim-b")
public interface BserverFeignService {
@RequestMapping(value = "/b/server", method = RequestMethod.POST)
String server();
}
b.服务B
pom文件和application.yml配置文件和服务A一致
启动类
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableEurekaClient
@EnableDiscoveryClient
public class BserverApplication {
public static void main(String []args){
SpringApplication.run(BserverApplication.class,args);
}
}
controller层
@RestController
@RequestMapping("/b")
@Slf4j
public class BserverController {
@PostMapping("/server")
public String b(){
log.info("b服务正在被调用");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "ok";
}
}
至此项目搭建完毕
项目结构图
kim-A为调用方
kim-B为被调用方
kim-eureka为注册中心
本项目使用的是2.23.2版本zipkin的jar包
项目git地址
https://gitee.com/kim_wu94/kim-sleuth-zipkin.git
测试接口
localhost:31001/a/server
查看zipkin
访问地址:127.0.0.1:9411
图中可以明确看到每次的调用信息
点击show后查看详情
关注公众号
每周会更新干货知识