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")); }
访问方式:
http://127.0.0.1:4001/member/test?user=100