SpringCloud
Spring cloud 是一系列框架的有序集合,主要用于微服务,解决分布式微服务架构的一站式解决方案,是多种微服务架构落地技术的集合体,简称微服务全家桶。
cloud和boot之间的依赖关系
地址:https://spring.io/projects/spring-cloud#overview
Cloud版本对应的SpringBoot版本
2023.0.x aka Leyton --- 3.2.x
2022.0.x aka Kilburn --- 3.0.x, 3.1.x (Starting with 2022.0.3)
2021.0.x aka Jubilee --- 2.6.x, 2.7.x (Starting with 2021.0.3)
Hoxton --- 2.2.x, 2.3.x (Starting with SR5)
Greenwich --- 2.1.x
Cloud每个组件
- 注册中心:Eureka、Zookeeper、Consul、Nacos
- 服务调用:Ribbon、LoadBalancer
- 服务调用:Feign、OpenFeign
- 服务降级:Hystrix、Sentinel
- 服务网关:Zuul、Gateway
- 服务配置:Config、Nacos
- 服务总栈:Bus、Nacos
服务注册与发现
什么是服务治理
管理服务之间依赖关系,可以实现服务调用、负载均衡、容错等,实现服务注册与发现。
Eureka
目前官网已停更
单机版
步骤1:创建一个注册中心服务,为服务端
步骤2:改POM文件
<dependencies>
<!--eureka-server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
步骤3:改yml文件
server:
port: 7001
eureka:
instance:
hostname: localhost #eureka服务端的实例名称
client:
#false表示不向注册中心注册自己。
register-with-eureka: false
#false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
fetch-registry: false
service-url:
#设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址。
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
步骤4:启动类增加注解
# 服务端的启动类增加该注解
@EnableEurekaServer
# 启动服务,进行访问注册中心的服务端
http://localhost:7001
步骤5:修改客户端,客户端服务注册到服务端上
<!--改客户端的POM文件,eureka-client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
步骤6:修改客户端yml文件
server:
port: 80
spring:
application:
# 该服务名
name: cloud1-order-80
eureka:
client:
# 表示是否将自己注册进EurekaServer默认为true。
register-with-eureka: true
# 是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetchRegistry: true
service-url:
defaultZone: http://localhost:7001/eureka
步骤7:启动类增加注解
# 客户端的启动类增加该注解
@EnableEurekaClient
# 启动服务,再次进行访问注册中心的服务端,会发现已有服务注册上服务端了
http://localhost:7001
集群Eureka版
步骤1:创建2台注册中心服务端,引包,其他步骤与单机一致
步骤2:改yml文件
# 注册中心1
erver:
port: 7002
eureka:
instance:
hostname: eureka7002.com #eureka服务端的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
# 注册另一台 eureka机器上
defaultZone: http://eureka7001.com:7001/eureka/
# 注册中心2
erver:
port: 7001
eureka:
instance:
hostname: eureka7001.com #eureka服务端的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
# 注册另一台 eureka机器上
defaultZone: http://eureka7002.com:7002/eureka/
步骤3:相互注册
# 启动服务,分别启动服务,查看互相注册成功没
http://localhost:7001
# 启动服务,分别启动服务,查看互相注册成功没
http://localhost:7002
步骤4:修改客户端yml文件
eureka:
client:
# 表示是否将自己注册进EurekaServer默认为true。
register-with-eureka: true
# 是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetchRegistry: true
service-url:
# 单机配置
# defaultZone: http://localhost:7001/eureka
# 集群配置
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
instance:
# 修改服务项目名称
instance-id: payment8001
# 访问路径可以显示IP地址,鼠标放在服务项目名称上,会显示IP地址
prefer-ip-address: true
Zookeeper
也可以当注册中心,它是一个临时节点,如果客户端挂了,也取消注册,客户端重启后,会产生新的id。
现在客户端连接Zookeeper,需要在Linux机器上安装服务端
步骤1:创建一个客户端,改POM文件
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
<version>3.1.0</version>
</dependency>
步骤3:改yml文件
server:
port: 8001
spring:
application:
name: cloud1-provider
# 客户端 - 连接zookeeper
cloud:
zookeeper:
connect-string: 127.0.0.1:81,127.0.0.1:82,127.0.0.1:83
步骤4:启动类增加注解
@EnableDiscoveryClient //服务发现
Consul
官网:https://www.consul.io/intro/index.html
下载:https://developer.hashicorp.com/consul/install
它是服务与发现和配置管理系统,底层是go语言开发的,它更专注CP、而Eureka是AP
启动服务
在安装目录,进入控制台(cmd)
# 查看 consul 版本号
consul --version
# 开发模式进行启动
consul agent -dev
# 启动成功,进行访问页面
http://localhost:8500
客户端进行连接服务端
步骤1:创建一个客户端,改POM文件
<!-- SpringCloud consul config 客户端配置 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-config</artifactId>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<!--SpringCloud consul discovery 客户端配置 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
步骤3:改yml文件
server:
port: 8001
spring:
application:
name: cloud1-provider
# 客户端 - 连接Consul
cloud:
consul:
host: localhost
port: 8500
discovery:
# hostname: 127.0.0.1
service-name: ${spring.application.name}
config:
profile-separator: '-' # 默认是,分割,现在以-分割,如:xxx-dev.yml
format: YAML
# 动态刷新 - 1秒钟就刷新,同步配置文件里的文件
watch:
wait-time: 1
步骤4:启动类增加注解
@EnableDiscoveryClient //服务发现
@RefreshScope // 动态刷新
Eureka更专注AP、而Zookeeper和consul更专注CP
负载均衡
Ribbon
它提供了多种策略:比如轮询、随机和根据响应时间加权重,默认的Eureka包已经集成了Ribbon
<!--单独的Ribbon包-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
根据特定算法中从服务列表中选取一个要访问的服务,一般常用算法:
// 定义为随机
// return new RandomRule();
// 先按照轮询,如果获取服务失败,再获取可用服务
// return new RetryRule();
// 轮询
// return new RoundRobinRule();
// 响应速度越快,权重越大,越容易被选择
// return new WeightedResponseTimeRule();
// 先过滤多次访访问故障的服务,选择一个并发量小的服务
// return new BestAvailableRule();
// 先过滤故障服务,选择并发量小的服务
// return new AvailabilityFilteringRule();
// 复合判断,所在区域性能,可用性选择服务
// return new ZoneAvoidanceRule();
自定义Ribbon指定规则:
步骤1:在启动类外,创建一个类
@Configuration
public class MyRule {
@Bean
public IRule myRule() {
// 定义为随机
return new RandomRule();
}
}
步骤2:启动类添加注解,再启动服务就可以
@RibbonClient(name = "服務端名称", configuration = MyRule.class)
服务调用
OpenFeign
是一个声明式的Web服务客户端,只需要创建一个接口,并填加注解就可以使用,它内置了Ribbon,调用这个接口,就可以调用服务。
使用:
步骤1:引依赖包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
步骤2:启动类添加注解
@EnableFeignClients
步骤3:配置yml,进行接口超时控制
# 设置feign客户端超时时间(OpenFeign默认支持ribbon)
ribbon:
# 指的是建立连接后从服务器读取到可用资源所用的时间
ReadTimeout: 5000
# 指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
ConnectTimeout: 5000
步骤4:创建接口
// 指向调用的服务名
@FeignClient(value = "CLOUD1-PROVIDER")
public interface AFeignService {
@GetMapping("/bill/get/{id}")
CommonResult get(@PathVariable("id") Long id);
}
// 使用
@Resource
private AFeignService aFeignService;
步骤5:超时控制和Httpclient5配置
默认等待是60秒,超时后会报错。
默认的使用JDK自带的HttpURLConnection没有连接池、性能低,可以使用httpclient5提升性能。
# 引用httpclient的包,因为这个有连接池,提高并发量
<!-- httpclient5-->
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.3</version>
</dependency>
<!-- feign-hc5-->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-hc5</artifactId>
<version>13.1</version>
</dependency>
配置文件
spring:
cloud:
openfeign:
client:
config:
# 默认的全局配置
default:
connectTimeout: 3000 # 连接超时时间
readTimeout: 3000 # 读取超时时间
# 开启 Httpclient5 配置
httpclient:
hc5:
enabled: true
# 对请求和响应进行 GZIP压缩
compression:
request:
enabled: true
min-request-size: 2048 # 最小触发压缩的大小
mime-types: text/xml,application/xml,application/json # 触发压缩数据类型
response:
enabled: true
配置类
@Configuration
public class FeignConfig {
@Bean
public Retryer myRetryer() {
return Retryer.NEVER_RETRY; // Feign默认配置是不走重试策略的
// 最大请求次数为3(1+2),初始间隔时间为100ms,重试间最大间隔时间为1s
// return new Retryer.Default(100,1,3); 【如果请求失败,会重试再次请求】
}
// feign的日志打印级别 NONE 、BASIC、HEADERS 、FULL
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
服务降级
Hystrix
它是处理分布式系统的延迟和容错的,多个服务之前调用的时候,很难避免调用失败、超时、异常等,它提供一个保障,不会整个服务都垮掉,提供服务的高可用。
服务降级
服务忙,不会让客户端一直等待,给个提示(fallback)
产生降级的因素:异常、超时、线程池满了、服务熔断触发了服务降级
服务熔断
达到最大请求量,直接拒绝访问
服务限流
高并发情况下,一共可以处理5个请求,大量的请求,大家进行排队,有序进来,如果处理不过来会直接放弃
服务限时
某个时间段,倒计时就开启几秒种访问,其他时间不可访问,如:京东抢飞天茅台
服务降级配置
一般都在客户端这边做服务降级
步骤1 启动类增加注解
@EnableHystrix
步骤2 修改yml配置文件
feign:
hystrix:
enabled: true
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 5000
# 设置feign客户端超时时间(OpenFeign默认支持ribbon)
ribbon:
# 指的是建立连接后从服务器读取到可用资源所用的时间
ReadTimeout: 5000
# 指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
ConnectTimeout: 5000
步骤3 Feign接口
@Service
@FeignClient(value = "服务端名称",fallback = 服务降级处理类.class)
public interface HystrixService {
// 正常请求 - 服务端的接口
@GetMapping("/t1/hystrix/{id}")
String ok(@PathVariable("id") Integer id);
// 超时请求 - 服务端的接口
@GetMapping("/t1/hystrix/timeout/{id}")
String timeOut(@PathVariable("id") Integer id);
}
步骤4 服务降级处理
@Component
public class 服务降级处理类 implements HystrixService {
Logger log = LoggerFactory.getLogger(getClass());
@Override
public String ok(Integer id) {
log.info("正常请求 - 服务端的接口 服务降级处理");
return "====正常请求 fall back ok,o(╥﹏╥)o====";
}
@Override
public String timeOut(Integer id) {
log.info("超时请求 - 服务端的接口 服务降级处理");
return "====超时请求 fall back timeOut,o(╥﹏╥)o====";
}
}
服务熔断配置
相当于保险丝,熔断就是长时间服务端调用失败,就会触发保险丝,一定的时间都无法访问到服务端接口,然后触发保险丝之后,会有个别请求服务接口,如果正常访问,会恢复正常状态。
/**
* 3 服务熔断
* fallbackMethod 熔断的处理类
* 在10秒 的时间内,必须达到20次请求,失败达到60次的比例,就触发熔断,下次请求,直接进行降级处理
* @param id
* @return {@link String}
*/
@HystrixCommand(fallbackMethod = "payBreakerFallback", commandProperties = {
@HystrixProperty(name = "circuitBreaker.enabled", value = "true"), // 是否开启断路器
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "5"), // 请求次数
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"), // 时间窗口期
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"), // 失败率达到多少后跳闸
})
@Override
public String payBreaker(@PathVariable("id") Integer id) {
if (id < 0) {
throw new RuntimeException("******id 不能负数");
}
return Thread.currentThread().getName() + "\t" + "调用成功,流水号: " + id;
}
/**
* 该服务降级的处理类
*
* @param id
* @return {@link String}
*/
public String payBreakerFallback(@PathVariable("id") Integer id) {
return "id 不能负数,服务降级处理 id: " + id;
}
服务监控
hystrixDashboard
对hystrix服务端进行监控
步骤1:引包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
步骤2:启动类增加注解
@EnableHystrixDashboard
// 然后在配置文件yml,进行增加端口号的基本配置
步骤3:启动服务
// 进行访问监控页面
http://localhost:9001/hystrix
// 打开页面,对那些服务进行监控,就在地址栏输入该服务,例:http://localhost:8001/hystrix.stream
Resilience4j
引包
<!-- 引入断路器依赖resilience4j -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
</dependency>
配置
resilience4j:
circuitbreaker:
configs:
# default是默认的规则
default:
# 设置百分比配置失败率。例:50% 会触发
failureRateThreshold: 50
# 滑动窗口的类型:COUNT_BASED (次数) TIME_BASED (时间),默认是 COUNT_BASED
slidingWindowType: COUNT_BASED
# 基数,如果总共请求10次,有50%的请求失败,就会触发熔断 、或者 如果总请求超过10秒内,会触发断路器
slidingWindowSize: 5
# 断路器计算失败率或慢调用率之前所需的最小样本(每个滑动窗口周期)。
# 如果minimumNumberOfCalls为10,则必须最少记录10个样本,然后才能计算失败率。如果只记录了9次调用,即使所有9次调用都失败,断路器也不会开启。
minimumNumberOfCalls: 5
# 是否启用 自动从开启状态过渡到半开状态,默认值为true
automaticTransitionFromOpenToHalfOpenEnabled: true
# 从OPEN到HALF_OPEN状态需要等待的时间,就是断路器,恢复到正常时间是5秒
waitDurationInOpenState: 5s
# 半开状态允许的最大请求数,默认值为10,断路器触发,进行N次调用,如果调用2次还是失败,直接继续保持断路器开启状态
permittedNumberOfCallsInHalfOpenState: 2
# 有哪些异常,会触发断路器
recordExceptions:
- java.lang.Exception
# 忽略哪个异常,不算触发熔断器
ignore-exceptions:
- java.lang.Throwable
# 这个断路器 -具体给谁配置
instances:
# 这个与 @CircuitBreaker设的name名字,需要保持一致
cloud-xxx:
base-config: default
使用
@GetMapping(value = "/test/{id}")
@CircuitBreaker(name = "cloud-xxx", fallbackMethod = "myFallback")
public String getById(@PathVariable("id") Integer id) {
return feignApi.test(id); // 远程调用的接口
}
// 服务降级 - 执行这里的逻辑
public String xxx(Integer id, Throwable t) {
System.out.println("服务降级的路径--------------");
return "系统繁忙";
}
它可以做服务降级/限流流控/控制最大并发限制等功能,详细在资源中心查看源码
网关
Spring Cloud Gateway
它为微服务架构提供有效的统一的API路由管理方式,底层使用了Netty通讯框架。可以做反向代理、鉴权、流量控制、熔断、日志监控。
它与Zuul的区别:
Zuul是基于IO的API网关,基于Servlet 2. 5使用阻塞架构。Spring Cloud Gateway它是使用非阻塞API。
三大核心:
- 路由:Route(如果断言正确,匹配该路由)
- 断言:Predicate(请求与断言是否匹配)
- 过滤:Filter(进行细化的控制)
创建新的服务当网关
步骤1:引包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
步骤2:修改yml
server:
port: 9527
spring:
application:
name: cloud-gateway
# 网关配置
cloud:
gateway:
discovery:
locator:
enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
- id: cloud1_provider_routh # 路由的ID,没有固定规则但要求唯一,建议配合服务名
# uri: http://localhost:8001 # 匹配后提供服务的路由地址(第一版,可以写固定的)
uri: lb://cloud1-provider # 匹配后提供服务的路由地址,与注册中心的服务名一致
predicates:
- Path=/t2/test1/** # 断言,路径相匹配的进行路由
- id: cloud1_pxx_routh
uri: lb://cloud1-pxx
predicates:
- Path=/pxx/test1/**
# 断言,当在这个时间之后可以使用该路由
- After=2022-03-08T23:14:51.718+08:00[Asia/Shanghai]
# 断言,当在这个时间之前可以使用该路由
- Before=2022-03-08T23:14:51.718+08:00[Asia/Shanghai]
# 断言 在这个范围之内
- Between=2022-02-02T17:45:06.206+08:00[Asia/Shanghai],2023-03-25T18:59:06.206+08:00[Asia/Shanghai]
# 断言,必须携带该Cookie,不带该Cookie会爆404
# 携带Cookie,
# 访问:curl http://localhost:9527/pxx/test1/xxxx --cookie “username=yan”
- Cookie=username,yan
# 断言,请求头要有X-Request-Id属性并且值为整数的正则表达式,否则会404,
# 请求 curl http://localhost:9527/pxx/xxx -H “X-Request-Id:-123”
- Header=X-Request-Id, \d+
# 断言,请求域名,必须以goodyan.com结尾,
# 请求 curl http://localhost:9527/pxx/xxx -H “Host: java.goodyan.com”
- Host=**.goodyan.com
# 断言,必须是get请求
- Method=GET
# 断言,要有参数名username并且值还要是整数才能路由
- Query=username, \d+
# 过滤器,路由过滤器只能指定路由进行使用,可用于修改进入的HTTP请求和返回的HTTP响应
filters:
# 过滤器工厂会在匹配的请求头加上一对请求头,名称为X-Request-Id值为1024
- AddRequestParameter=X-Request-Id,1024
eureka:
client:
# 表示是否将自己注册进EurekaServer默认为true。
register-with-eureka: true
# 是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetchRegistry: true
service-url:
# 单机配置
# defaultZone: http://localhost:7001/eureka
# 集群配置 ,可以配置域名,修改本地host文件
# defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
defaultZone: http://127.0.0.1:7001/eureka,http://127.0.0.1:7002/eureka
instance:
# 修改服务项目名称
instance-id: gateway9527
# 访问路径可以显示IP地址,鼠标放在服务项目名称上,会显示IP地址
prefer-ip-address: true
# Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒)
lease-renewal-interval-in-seconds: 30
# Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除服务
lease-expiration-duration-in-seconds: 90
步骤3:进行测试
// 访问服务端机器1:http://localhost:8001/t2/test1/6
// 访问服务端机器2:http://localhost:8003/t2/test1/6
// 访问网关地址: http://localhost:9527/t2/test1/6
配置中心
SpringCloud Config
它可以集中管理配置文件、不同环境动态化配置更新,当配置文件发送改变,不需要重启感知最新服务。
它需要有一个配置中心服务端,获gitee上的取配置文件,然后配置中心客户端需求获取配置中心的地址,来获取最新的配置文件,但如今已被叫Nacos替代,不再演示。
SpringCloud Bus
它是消息总线,是分布式自动刷新配置功能,经常与SpringCloud Config配合使用。但如今也被Nacos替代,不再演示。
消息驱动
SpringCloud Stream
它是统一消息的编程模型,
官网:https://spring.io/projects/spring-cloud-stream#overview
MQ思想:
- 生产者/消费者之间靠消息媒介传递信息内容——Message
- 消息必须走特定的通道——消息通道MessageChannel
- 通道里的消息,由MessageHandler消息处理器所订阅
具体的代码演示,在gitee上有分享
链路跟踪
SpringCloud Sleuth
它记录每一个请求都会形成一条复杂的分布式服务调用链路,链路中的任何一环出现高延时或错误都会引起整个请求最后的失败。
步骤1:安装zipkin
下载zipkin的jar包,然后进行运行启动
java -jar zipkin-server-2.12.9-exec.jar
运行控制台:http://localhost:9411/zipkin/
步骤2:然后每个服务,客户端引包
<!--包含了sleuth+zipkin-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
步骤3:
spring:
# 链路跟踪(该zipkin服务地址 9411)
zipkin:
base-url: http://localhost:9411
sleuth:
sampler:
# 采样率值介于 0 到 1 之间,1 则表示全部采集
probability: 1
演示:
需要启动:
客户端80端口、8001端口服务、启动注册中心
启动zipkin的服务端,端口9411
访问:请求http://localhost/k1/get2/6 请求,再去9411端口服务,查看该服务的链路跟踪
Micrometer Tracing
解决:在规模分布式集群下,监控实时观测系统的整体调用链路情况、快速定位发现问题、梳理服务之间的依赖关系、分析系统调用链路的性能和瓶颈点、规划系统存储瓶颈和容量规划。
分布式链路追踪技术:Cat、ZipKin(开源分布式跟踪系统,集成方便)、Skywalking(支持多种插件,UI功能强大,推荐)、Pinpoint
zipkin
官网:https://zipkin.io/
它是分布式链路跟踪系统图形化工具,我们需要安装它,需要去官网下载,下载成功是一个jar包文件
运行
java -jar zipkin-server-3.3.0-exec.jar
启动成功,进行访问
http://localhost:9411/zipkin/