概述
Gateway 底层基于 Netty 异步通讯的,使用的是 Webflux 框架处理请求。
本文中所用到的 Spring Cloud 和 Spring Boot 相关的版本说明
版本概述: spring-boot 2.4.2 spring-cloud 2020.0.1
服务注册: eureka-client
服务熔断: reactor-resilience4j
本文主要是通过一个 demo 来对 Gateway 的核心功能进行简要的介绍。
demo 项目地址. github 地址
Gateway 核心功能
一. 路由
- 配置负载均衡
uri: lb://SERVICE-MEMBER
这里 lb 就是用到了负载均衡, 由于我这里使用的是 eureka-client 3.0.1 内部使用的是loadbalancer 作为负载均衡框。
- 配置断言
predicates:
# 路由断言对符合条件的接口断言
- Path=/member/**
predicates 下面的所有配置信息都是对服务节点接口的断言,我们还可以对参数, cookie, header 等各方面进行断言
- 配置过滤器
filters:
# 熔断器
- name: CircuitBreaker
args:
name: myCircuitBreaker
fallbackUri: forward:/fallback
gatway 还提供过滤器的配置,支持自定义过滤器,来控制路由规则
二. 鉴权
实现鉴权咱们的主要主要实现手段是通过 GlobalFilter 的方式来实现的,下面是一个简单的例子判断咱们 cookie 中是否包含 login 信息。如果包含就表示用于已经登录,如果没有就返回 UNAUTHORIZED
- 对用户登录进行鉴权,首先定义全局过滤器
/**
* 自定义登录过滤器判断是否登录
*
* @author zhengsh
* @date 2021-01-31
*/
public class LoginFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
MultiValueMap<String, HttpCookie> cookies = exchange.getRequest().getCookies();
for (Map.Entry<String, List<HttpCookie>> cookie : cookies.entrySet()) {
// 如果 cookie 中包含 login 信息就表示通过
if (cookie.getKey().equals("login")) {
System.out.println(1);
return chain.filter(exchange);
}
}
System.out.println(2);
// 401
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
@Override
public int getOrder() {
return -1;
}
}
三. 降级/熔断
resilience4j 进行服务降级
filters:
# 熔断器
- name: CircuitBreaker
args:
name: myCircuitBreaker
fallbackUri: forward:/fallback
Resilience4j 是一个受hystrix启发的一款轻量级容错类库, 在分布式系统中,许多不可避免的调用会失败, 比如超时,一场等。Resilience4j 能够保证在一个依赖出现问题的情况下,不会导致整体服务失败,避免级联故障,提高分布式系统的弹性。
“断路器” 本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似保险熔断),向调用方法返回一个符合预期的,可处理的被选相应(FallBack), 而不是长时间的等待或者跑出调用方法无法处理的异常,这样就保证了服务调用方的线程不会长时间,不必要地占用,从而避免了故障在分布式系统中进行蔓延,从而导致雪崩效应。
四. 限流
通过 gateway 自带的 redislimiter 算法进行限流
配置参数:
filters:
# 令牌桶
- name: RequestRateLimiter
KeyResolver: userKeyResolver
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
redis-rate-limiter.requestedTokens: 1
userKeyResolver 定义
@Bean
public KeyResolver userKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}
访问方式: