SpringCloudGateway学习(3)-重试,熔断,限流
前两章文件主要概述了Gateway的三大组件,现在我们继续学习Gateway的其他作用熔断和限流。Gateway是一个网关项目, 网关可以是整个微服务API请求的入口,负责拦截所有请求,分发到服务上去。可以实现日志拦截、权限控制、解决跨域问题、限流、熔断、负载均衡,隐藏服务端的ip,黑名单与白名单拦截、授权等。
1.概述
前两章文件主要概述了Gateway的三大组件,现在我们继续学习Gateway的其他作用熔断和限流。Gateway是一个网关项目, 网关可以是整个微服务API请求的入口,负责拦截所有请求,分发到服务上去。可以实现日志拦截、权限控制、解决跨域问题、限流、熔断、负载均衡,隐藏服务端的ip,黑名单与白名单拦截、授权等。
2.重试机制
重试机制就是gateway检测到异常,然后就开始进行重试
引入依赖
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
过滤器配置重试过滤器
spring:
cloud:
gateway:
routes: #1路由
- id: producer-one
uri: lb://producter-one
predicates: #2通过path断言
- Path=/*/producterone/**
filters: #3过滤器,过滤器可以不用配置
- StripPrefix=1 #截断请求PATH
- name: Retry #重试过滤器
args:
retries: 3 #重试次数
series: SERVER_ERROR
methods: GET,POST
- id: producer-two
uri: http://localhost:8080
predicates:
- Path=/*/productertwo/
filters:
- StripPrefix=1
retries:重试次数
series: SERVER_ERROR,下游服务报5XX系列的错误触发重试机制
methods:重试的HTTP方法
3. 熔断降级Hystrix
熔断降级:在分布式系统中,网关作为流量的入口,大量请求进入网关,向后端远程系统或服务发起调用,后端服务不可避免的会产生调用失败(超时或者异常),失败时不能让请求堆积在网关上,需要快速失败并返回回去,这就需要在网关上做熔断、降级操作。
引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>${spring.cloud.version}</version>
</dependency>
增加熔断降级接口
@RestController
public class GatewayController {
@GetMapping("fallback")
public String hello() {
return "Hystrix 熔断降级";
}
}
增加熔断过滤器以及配置熔断时间(熔断时间<Gateway超时时间,不然会先触发gateway超时不会触发熔断)
spring:
application:
name: gateway-server
cloud:
gateway:
routes: #1路由
- id: producer-one
uri: lb://producter-one
predicates: #2通过path断言
- Path=/*/producterone/**
filters: #3过滤器,过滤器可以不用配置
- StripPrefix=1 #截断请求PATH,去掉前缀gateway再请求
#局部过滤器熔断Hystrix
- name: Hystrix
args:
name: localfallback
fallbackUri: forward:/gateway/fallback #熔断转发到其他URL
- id: producer-two
uri: http://localhost:8080
predicates:
- Path=/*/productertwo/
filters:
- StripPrefix=1
httpclient: #全局设置gateway超时设置
response-timeout: 30000 #必须以毫秒为单位指定响应超时时间.
connect-timeout: 30000 #必须以毫秒为单位指定连接超时时间.
## hystrix ,3秒后自动超时
hystrix:
command:
default: #default全局有效,service id指定应用有效
execution:
timeout:
enabled: true #如果enabled设置为false,则请求超时交给ribbon控制,为true,则超时作为熔断根据
isolation:
thread:
timeoutInMilliseconds: 3000
4.限流
限流:网关上有大量请求,对指定服务进行限流,可以很大程度上提高服务的可用性与稳定性,限流的目的是通过对并发访问/请求进行限速,或对一个时间窗口内的请求进行限速来保护系统。一旦达到限制速率则可以拒绝服务、排队或等待、降级,同一时间限制访问的人数。
限流框架:基于 redis和阿里开源的限流神器 Sentinel
限流的算法:
1.漏桶算法:把请求放到一个容器中,控制处理的速度
2. 令牌算法:给每一个请求分配一个令牌,没有令牌的访问不了,1/QPS (同一时间接口的访问数一般一个tomcat是200~250)。
这里就用redis实现限流。
引入redis连接依赖
#未设置版本号,使用spring-boot-starter-parent的
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
增加KeyResolver的实例
@Configuration
@Slf4j
public class CustomeKeyResolverConfig {
@Primary
@Bean(value = "hostAddKeyResolver")
public KeyResolver hostAddKeyResolver() {
// 根据IP地址限流
KeyResolver keyResolver = (exchange) -> {
String hostAddress = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
log.info("hostAddress={}", hostAddress);
return Mono.just(hostAddress);
};
return keyResolver;
}
@Bean("uriPathKeyResolver")
public KeyResolver uriPathKeyResolver() {
// 根据请求地址限流
KeyResolver keyResolver = (exchange) -> {
String uriPath = exchange.getRequest().getURI().getPath();
log.info("uriPath={}", uriPath);
return Mono.just(uriPath);
};
return keyResolver;
}
}
配置访问限制过滤器RequestRateLimiter
spring:
application:
name: gateway-server
cloud:
gateway:
routes: #1路由
- id: producer-one
uri: lb://producter-one
predicates: #2通过path断言
- Path=/*/producterone/**
filters: #3过滤器,过滤器可以不用配置
- StripPrefix=1 #截断请求PATH,去掉前缀gateway再请求
#局部过滤器熔断Hystrix
- name: Hystrix
args:
name: localfallback
fallbackUri: forward:/gateway/fallback #熔断转发到其他URL
#局部过滤器熔断RequestRateLimiter
- name: RequestRateLimiter
args:
key-resolver: '#{@hostAddKeyResolver}' # 使用SpEL名称引用Bean
redis-rate-limiter.replenishRate: 1 #每秒最大访问次数
redis-rate-limiter.burstCapacity: 3 #令牌桶最大容量
- id: producer-two
uri: http://localhost:8080
predicates:
- Path=/*/productertwo/
filters:
- StripPrefix=1
httpclient: #全局设置gateway超时设置
response-timeout: 30000 #必须以毫秒为单位指定响应超时时间.
connect-timeout: 30000 #必须以毫秒为单位指定连接超时时间.
## hystrix ,3秒后自动超时
hystrix:
command:
default: #default全局有效,service id指定应用有效
execution:
timeout:
enabled: true #如果enabled设置为false,则请求超时交给ribbon控制,为true,则超时作为熔断根据
isolation:
thread:
timeoutInMilliseconds: 3000
# redis连接配置
redis:
host: 127.0.0.1
port: 36379
password: redis
database: 0
filter名称必须是RequestRateLimiter
redis-rate-limiter.replenishRate:允许用户每秒处理多少个请求
redis-rate-limiter.burstCapacity:令牌桶的容量,允许在一秒钟内完成的最大请求数
key-resolver:使用SpEL按名称引用bean
启动服务频繁访问
5.其他方式限流
方式1:阿里开源限流神器:Sentinel
方式2:自定义过滤器实现令牌桶算法限流
参考:
更多推荐
所有评论(0)