一、网关熔断 1.引入依赖熔断
在分布式系统中,网关作为流量的入口,大量请求进入网关,向后端远程系统或服务发起调用,后端服务不可避免的会产生调用失败(超时或者异常),失败时不能让请求堆积在网关上,需要快速失败并返回回去,这就需要在网关上做熔断、降级操作。
限流
网关上有大量请求,对指定服务进行限流,可以很大程度上提高服务的可用性与稳定性,限流的目的是通过对并发访问/请求进行限速,或对一个时间窗口内的请求进行限速来保护系统。一旦达到限制速率则可以拒绝服务、排队或等待、降级。
2.添加熔断处理器org.springframework.cloud spring-cloud-starter-gateway ${gateway.version} org.springframework.cloud spring-cloud-starter-netflix-hystrix
@Slf4j
@RestController
public class FallbackHandler {
@RequestMapping("/defaultfallback")
public Map defaultfallback(HttpServerRequest request) {
String uri = request.uri();
log.warn("网关熔断,url:{}",uri);
Map map = new HashMap<>();
map.put("code","5001");
map.put("msg","服务异常,请稍后重试");
map.put("data","null");
return map;
}
}
3.修改配置
- id: api-product
uri: lb://api-product
predicates:
- Path=/api-product
@Bean("ipKeyResolver")
KeyResolver ipKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
}
@Primary
@Bean("apiKeyResolver")
public KeyResolver apiKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getPath().value());
}
@Bean("userKeyResolver")
public KeyResolver userKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("userId"));
}
}
3.添加配置
- id: facade-product
uri: lb://facade-product
predicates:
- Path=/api-product/**
filters:
- StripPrefix=1
# 熔断过滤器
- name: Hystrix
args:
name: defaultfallback
fallbackUri: forward:/defaultfallback
# 限速路由器
- name: RequestRateLimiter
args:
# 限流策略
key-resolver: "#{@ipKeyResolver}"
# 每秒允许处理的请求数量,令牌桶每秒填充平均速率
redis-rate-limiter.replenishRate: 10
# 令牌桶的容量,允许在一秒钟内完成的最大请求数
redis-rate-limiter.burstCapacity: 10
4.测试
使用jmeter或者postman进行测试
(1)1秒内10个线程并发访问一个接口,访问全部通过
(2)1秒内100个线程并发访问一个接口,大部分的访问被拦截,通过率只有20%(存在一定的误差),被拦截的请求返回的header携带Response message:Too Many Requests
虽然存在一定的误差,但是限流已经成功。不过gateway官方提供的限流只能使用一种限流策略,也就是你只能针对IP或者接口选择一种方式进行限流,无法做到同时即限制IP又限制接口的策略,存在一定的局限性。如果想要同时做到多规则限流的小伙伴可以关注我看下一篇自定义多规则限流篇



