【Spring Cloud一】微服务基本知识
【Spring Cloud 三】Eureka服务注册与服务发现
【Spring Cloud 四】Ribbon负载均衡
【Spring Cloud 五】OpenFeign服务调用
【Spring Cloud 六】Hystrix熔断
目前开发的项目正是使用sleuth+zipkin的方式进行的链路追踪,为了对sleuth+zipkin这个技术点加深认识。博主对其进行了理论学习和实践。
链路追踪就是追踪微服务的调用路径。
随着业务越来越复杂,以及微服务架构的兴起,在微服务架构中,一个由客户端发起的请求在后端往往会经过不同的服务节点调用协同完成一个请求。当请求出现问题(不可用,请求时间长等等),我们很难定位到具体是哪一个或者哪几个服务出现了问题,而链路追踪能够帮助我们快速精准的定位到是哪一个服务出现了问题。
Sleuth是Spring Cloud提供的一款分布式系统跟踪解决方案,Sleuth可以自动为每一个请求添加唯一的跟踪标识,以便在整个请求链路中跟踪与识别请求。
学习Sleuth之前必须了解它的几个概念,它们是实现链路追踪的基础:
Zipkin是一个开源的分布式跟踪系统,它收集并存储跨多个服务的请求链路数据,并提供支援的Web界面吗用于查看和分析这些数据。帮助开发人员快速定位和解决分布式系统中的性能问题。
zipkin的运行关系图:
图片来自官网:https://zipkin.io/pages/architecture.html
zipkin的大致运行流程:
集成zipkin客户端服务通过几种传输(http,kafka,scribe)之一将数据发送到zipkin服务端,Collector将跟踪数据保存到Storage,之后Storage通过API向UI提供数据。
部分名词解释:
1.InstrumentedClient:使用了Zipkin客户端工具的服务调用方
2.InstrumentedServer:使用了Zipkin客户端工具的服务提供方
3.Non-InstrumentedServer:未使用Zipkin客户端工具的服务提供方
Sleuth和Zipkin通常一起使用来实现分布式系统的请求链路跟踪和性能监控。 Sleuth主要负责为每个请求添加唯一的跟踪标识,并将跟踪信息传递给下游服务。而Zipkin主要负责负责收集和存储这些跟踪信息,并通过可视化界面展示整个请求链路的信息,包括请求的时间、调用的顺序以及每个调用的耗时等
补充:其实完全可以单独使用Zipkin进行链路追踪,但是为什么大多数都选择使用Sleuth+Zipkin?
Spring Cloud从F版本之后可以不需要自己构建Zipkin服务了,只需要调用jar就可以。
下载Zipkin jar包 https://repo1.maven.org/maven2/io/zipkin/zipkin-server/2.24.3/
下载之后直接在本机运行 java -jar +jar包所在路径
该项目总共有四个服务,一个Zipkin服务端、一个Eureka服务端、一个服务提供者,一个服务消费者。
如何搭建Eurka服务可以访问这篇博客【Spring Cloud 三】Eureka服务注册与服务发现
<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>feign-projectartifactId>
<groupId>com.wangweigroupId>
<version>1.0-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>order-centerartifactId>
<properties>
<maven.compiler.source>8maven.compiler.source>
<maven.compiler.target>8maven.compiler.target>
properties>
<dependencies>
<dependency>
<groupId>com.wangweigroupId>
<artifactId>common-apiartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
server:
port: 8080
spring:
application:
name: order-service
zipkin:
base-url: http://localhost:9411
sleuth:
sampler:
probability: 1 #配置采样率 默认的采样比例为0.1 即10%,所设置的值介于0到1之间,1表示全部采集
rate: 10 #为了使用速率限制采样器,选择每秒间隔接收的trace量,最小数字为0,最大值为2,147,483,647(最大int) 默认为10
eureka:
client:
service-url: #??????
defaultZone: http://localhost:8761/eureka
register-with-eureka: true #设置为fasle 不往eureka-server注册
fetch-registry: true #应用是否拉取服务列表到本地
registry-fetch-interval-seconds: 10 #为了缓解服务列表的脏读问题,时间越短脏读越少 性能相应的消耗回答
instance: #实例的配置
instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port}
hostname: localhost #主机名称或者服务ip
prefer-ip-address: true #以ip的形式显示具体的服务信息
lease-renewal-interval-in-seconds: 10 #服务实例的续约时间间隔
@SpringBootApplication
@EnableEurekaClient
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class,args);
}
}
@RestController
public class OrderController {
@GetMapping("order/getOrderByUserId/{id}")
Order getOrderByUserId (@PathVariable("id")Integer id){
System.out.println(id);
Order order=Order.builder()
.name("青椒肉丝盖饭")
.price(15D)
.orderId(1)
.build();
return order;
}
}
<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>feign-projectartifactId>
<groupId>com.wangweigroupId>
<version>1.0-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>common-apiartifactId>
<properties>
<maven.compiler.source>8maven.compiler.source>
<maven.compiler.target>8maven.compiler.target>
properties>
<dependencies>
<dependency>
<groupId>com.wangweigroupId>
<artifactId>project-domainartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-openfeignartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-hystrixartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-zipkinartifactId>
dependency>
dependencies>
project>
@FeignClient(value = "order-service",fallback = UserOrderFeignHystrix.class)
public interface UserOrderFeign {
@GetMapping("order/getOrderByUserId/{id}")
Order getOrderByUserId (@PathVariable("id")Integer id);
}
@Component
public class UserOrderFeignHystrix implements UserOrderFeign {
/**
* 一般远程调用的熔断可以直接返回null
* @param id
* @return
*/
@Override
public Order getOrderByUserId(Integer id) {
return null;
}
}
<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>feign-projectartifactId>
<groupId>com.wangweigroupId>
<version>1.0-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>user-centerartifactId>
<properties>
<maven.compiler.source>8maven.compiler.source>
<maven.compiler.target>8maven.compiler.target>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
<dependency>
<groupId>com.wangweigroupId>
<artifactId>common-apiartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
dependencies>
project>
server:
port: 8081
spring:
application:
name: user-service
zipkin:
base-url: http://localhost:9411
sleuth:
sampler:
probability: 1 #配置采样率 默认的采样比例为0.1 即10%,所设置的值介于0到1之间,1表示全部采集
rate: 10 #为了使用速率限制采样器,选择每秒间隔接收的trace量,最小数字为0,最大值为2,147,483,647(最大int) 默认为10
eureka:
client:
service-url: #??????
defaultZone: http://localhost:8761/eureka
register-with-eureka: true #设置为fasle 不往eureka-server注册
fetch-registry: true #应用是否拉取服务列表到本地
registry-fetch-interval-seconds: 10 #为了缓解服务列表的脏读问题,时间越短脏读越少 性能相应的消耗回答
instance: #实例的配置
instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port}
hostname: localhost #主机名称或者服务ip
prefer-ip-address: true #以ip的形式显示具体的服务信息
lease-renewal-interval-in-seconds: 10 #服务实例的续约时间间隔
feign:
hystrix:
enabled: true #开启熔断
management:
endpoints:
web:
exposure:
include: '*'
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class,args);
}
}
@RestController
public class UserController {
@Autowired
private UserOrderFeign userOrderFeign;
@GetMapping("findOrder")
public Order findOrder(){
return userOrderFeign.getOrderByUserId(1);
}
}
先启动Eureka服务端在启动zipkin服务端,再启动服务提供者最后启动服务消费者。