目录
服务断路器_Resilience4j重试机制
服务断路器_Resilience4j异常比例熔断降级
服务断路器_Resilience4j慢调用比例熔断降级
服务断路器_Resilience4j信号量隔离实现
服务断路器_Resilience4j线程池隔离实现
服务断路器_Resilience4j限流
服务网关Gateway_微服务中的应用
为什么要使用服务网关
服务断路器_Resilience4j重试机制
重试机制比较简单,当服务端处理客户端请求异常时,服务端将会开启重试机制,重试期间内,服务端将每隔一段时间重试业务逻辑处理。 如果最大重试次数内成功处理业务,则停止重试,视为处理成功。如果在最大重试次数内处理业务逻辑依然异常,则此时系统将拒绝该请求。
修改YML文件
resilience4j:
retry:
instances:
backendA:
# 最大重试次数
maxRetryAttempts: 3
# 固定的重试间隔
waitDuration: 10s
enableExponentialBackoff: true
exponentialBackoffMultiplier: 2
服务提供者新增controller方法
/**
* 重试机制
* @return
*/
@GetMapping("/retry")
@Retry(name = "backendA")
public CompletableFuture<String> retry() {
log.info("********* 进入方法 ******");
//异步操作
CompletableFuture<String> completableFuture = CompletableFuture
.supplyAsync((Supplier<String>) () -> (paymentFeignService.index()));
log.info("********* 离开方法 ******");
return completableFuture;
}
服务断路器_Resilience4j异常比例熔断降级
给coud-consumer-feign-order80添加resilience4j依赖
修改yml文件
resilience4j.circuitbreaker:
configs:
default:
# 熔断器打开的失败阈值
failureRateThreshold: 30
# 默认滑动窗口大小,circuitbreaker使用基于计数和时间范围欢动窗口聚合统计失败率
slidingWindowSize: 10
# 计算比率的最小值,和滑动窗口大小去最小值,即当请求发生5次才会计算失败率
minimumNumberOfCalls: 5
# 滑动窗口类型,默认为基于计数的滑动窗口
slidingWindowType: TIME_BASED
# 半开状态允许的请求数
permittedNumberOfCallsInHalfOpenState: 3
# 是否自动从打开到半开
automaticTransitionFromOpenToHalfOpenEnabled: true
# 熔断器从打开到半开需要的时间
waitDurationInOpenState: 2s
recordExceptions:
- java.lang.Exception
instances:
backendA:
baseConfig: default
编写OrderController
/**
* 异常比例熔断降级
* @return
*/
@GetMapping("/citcuitBackend")
@CircuitBreaker(name = "backendA")
public String citcuitBackend(){
log.info("************ 进入方法***********");
String index = paymentFeignService.index();
log.info("************ 离开方法***********");
return index;
}
使用JMeter进行压力测试
修改语言
创建线程组
创建取样器HTTP请求
添加查看结果树
修改线程数量
修改HTTP请求参数
半开状态只有三次请求
编写降级方法
/**
* 异常比例熔断降级
* @return
*/
@GetMapping("/citcuitBackend")
@CircuitBreaker(name = "backendA")
public String citcuitTest(){
log.info("************ 进入方法***********");
String index =paymentFeignService.index();
log.info("************ 离开方法***********");
return index;
}
/**
* 服务降级方法
* @param e
* @return
*/
public String fallback(Throwable e){
e.printStackTrace();
return "客官服务繁忙,稍等一会。。。。";
}
测试降级方法
1 关闭服务提供者
2 服务消费者发起请求
产生服务降级
服务断路器_Resilience4j慢调用比例熔断降级
编写OrderController
/**
* 慢调用比例熔断降级
* @return
*/
@GetMapping("/slowcircuitbackend")
@CircuitBreaker(name = "backendB",fallbackMethod = "slowfallback")
public String slowcircuitbackend(){
log.info("************ 进入方法***********");
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
String index = paymentFeignService.index();
log.info("************ 离开方法***********");
return index;
}
编写yml文件
resilience4j.circuitbreaker:
configs:
default:
# 熔断器打开的失败阈值
failureRateThreshold: 30
# 默认滑动窗口大小,circuitbreaker使用基于计数和时间范围欢动窗口聚合统计失败率
slidingWindowSize: 10
# 计算比率的最小值,和滑动窗口大小去最小值,即当请求发生5次才会计算失败率
minimumNumberOfCalls: 5
# 滑动窗口类型,默认为基于计数的滑动窗口
slidingWindowType: TIME_BASED
# 半开状态允许的请求数
permittedNumberOfCallsInHalfOpenState: 3
# 是否自动从打开到半开
automaticTransitionFromOpenToHalfOpenEnabled: true
# 熔断器从打开到半开需要的时间
waitDurationInOpenState: 2s
recordExceptions:
- java.lang.Exception
instances:
backendA:
baseConfig: default
backendB:
# 熔断器打开的失败阈值
failureRateThreshold: 50
# 慢调用时间阈值 高于这个阈值的
slowCallDurationThreshold: 2s
# 慢调用百分比阈值,断路器吧调用事件大于slow
slowCallRateThreshold: 30
slidingWindowSize: 10
slidingWindowType: TIME_BASED
minimumNumberOfCalls: 2
permittedNumberOfCallsInHalfOpenState:2
waitDurationInOpenState: 2s
eventConsumerBufferSize: 10
服务断路器_Resilience4j信号量隔离实现
POM引入依赖
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-bulkhead</artifactId>
<version>1.7.0</version>
</dependency>
信号量隔离修改YML文件
resilience4j:
#信号量隔离
bulkhead:
instances:
backendA:
# 隔离允许并发线程执行的最大数量
maxConcurrentCalls: 5
# 当达到并发调用数量时,新的线程的阻塞时间
maxWaitDuration: 20ms
编写controller
/**
* 测试信号量隔离
* @return
*/
@Bulkhead(name = "backendA",type = Bulkhead.Type.SEMAPHORE)
@GetMapping("bulkhead")
public String bulkhead() throws InterruptedException {
log.info("************** 进入方法*******");
TimeUnit.SECONDS.sleep(10);
String index = paymentOpenFeignService.index();
log.info("************** 离开方法*******");
return index;
}
测试
配置隔离并发线程最大数量为5
服务断路器_Resilience4j线程池隔离实现
线程池隔离配置修改YML文件
resilience4j:
thread-pool-bulkhead:
instances:
backendA:
# 最大线程池大小
maxThreadPoolSize: 4
# 核心线程池大小
coreThreadPoolSize: 2
# 队列容量
queueCapacity: 2
编写controller
/**
* 测试线程池服务隔离
* @return
*/
@Bulkhead(name = "backendA",type = Bulkhead.Type.THREADPOOL)
@GetMapping("/futrue")
public CompletableFuture future(){
log.info("********** 进入方法*******");
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("********** 离开方法*******");
return CompletableFuture.supplyAsync(() -> "线程池隔离信息......");
}
测试
配置文件设置核心线程2个最大4个服务会一次处理4个请求
服务断路器_Resilience4j限流
限流YML配置
ratelimiter:
instances:
backendA:
# 限流周期时长。 默认:500纳秒
limitRefreshPeriod: 5s
# 周期内允许通过的请求数量。 默认:50
limitForPeriod: 2
先写Controller
/**
* 限流
* @return
*/
@GetMapping("/limiter")
@RateLimiter(name = "backendA")
public CompletableFuture<String> RateLimiter() {
log.info("********* 进入方法 ******");
//异步操作
CompletableFuture<String> completableFuture = CompletableFuture
.supplyAsync((Supplier<String>) () ->(paymentFeignService.index()));
log.info("********* 离开方法 ******");
return completableFuture;
}
JMeter压测
线程数 - 5
服务网关Gateway_微服务中的应用
没有服务网关
问题:
1 地址太多
2 安全性
3 管理问题
为什么要使用服务网关
网关是微服务架构中不可或缺的部分。使用网关后,客户端和微服务之间的网络结构如下。
注意: 网关统一向外部系统(如访问者、服务)提供REST API。在 SpringCloud 中,使用Zuul、Spring Cloud Gateway等作为API Gateway来实现动态路由、监控、回退、安全等功能。
认识Spring Cloud Gateway
Spring Cloud Gateway 是 Spring Cloud生态系统中的网关,它是基于Spring 5.0、SpringBoot 2.0和Project Reactor等技术开发的, 旨在为微服务架构提供一种简单有效的、统一的API路由管理方式, 并为微服务架构提供安全、监控、指标和弹性等功能。其目标是替代Zuul。
注意: Spring Cloud Gateway 用"Netty + Webflux"实现,不要加入 Web依赖,否则会报错,它需要加入Webflux依赖。
什么是WebFlux
Webflux模式替换了旧的Servlet线程模型。用少量的线程处理 request和response io操作,这些线程称为Loop线程,而业务交给响应式编程框架处理,响应式编程是非常灵活的,用户可以将业务中阻塞的操作提交到响应式框架的work线程中执行,而不阻塞的操作依然可以在Loop线程中进行处理,大大提高了Loop线程的利用 率。
注意:
Webflux虽然可以兼容多个底层的通信框架,但是一般情况下, 底层使用的还是Netty,毕竟,Netty是目前业界认可的最高性能的通信框架。而Webflux的Loop线程,正好就是著名的 Reactor模式IO处理模型的Reactor线程,如果使用的是高性能的通信框架Netty。
温馨提示:
什么是Netty,Netty 是一个基于NIO的客户、服务器端的编程 框架。提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。
Spring Cloud Gateway特点
1、易于编写谓词( Predicates )和过滤器( Filters ) 。其Predicates和Filters可作用于特定路由。
2、支持路径重写。
3、支持动态路由。
4、集成了Spring Cloud DiscoveryClient。
实时效果反馈
1.Spring Cloud Gateway 是 Spring Cloud生态系统中的_____。
A 断路器
B 注册发现服务
C 网关
D 以上都不是
2.下列不属于服务网关Gateway特点得是____。
A 支持路径重写
B 支持动态路由
C 服务熔断
D 集成服务发现