练习Spring Cloud Alibaba 6 ——Spring Cloud Gateway

网关——Spring Cloud Gateway

1.Spring Cloud Gateway介绍

网关的作用

网关作为流量的,在微服务系统中有着非常作用,网关常见的功能有路由转发、权限校验、限流控制等作用。

Spring Cloud Gateway
  • Spring Cloud Gateway是Spring Cloud官方推出的第二代网关框架,取代Zuul网关。
  • Spring Cloud Gateway是基于Netty,Reator以及WebFlux构建
Spring Cloud Gateway的优点
  • 性能强劲:Spring Cloud Gateway是第一代网关Zuul 1.X性能的1.6倍。
  • 功能强大:内置很多使用功能,比如转发、监控、限流等
Spring Cloud Gateway的缺点
  • 依赖Netty与WebFlux,不是Servlet编程模型,有一点的适应成本
  • 不能在Servlet容器下工作,也不能构建成WAR包
  • 不支持Spring Boot 1.X

2.Spring Cloud Gateway使用

新建项目gateway

pom添加依赖
<dependency>
   <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-gatewayartifactId>
dependency>
yml文件配置
server:
  port: 8040
spring:
  application:
    name: gateway
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    gateway:
      discovery:
        locator:
          # 让gateway通过服务发现组件找到其他的微服务
          enabled: true
management:
  endpoints:
    web:
      exposure:
        include: '*'
  endpoint:
    health:
      show-details: always
logging:
  level:
    org.springframework.cloud.gateway: trace
启动项目,使用gateway访问user-center

注意: Spring Cloud Gateway的转发规律,访问&{GATEWAY_URL}/{微服务}/**会转发到微服务X的/**路径
练习Spring Cloud Alibaba 6 ——Spring Cloud Gateway_第1张图片

2.Spring Cloud Gateway的核心概念

Route、Predicate、Filter
  • Route(路由)
    Spring Cloud Gateway的基础元素,可简化理解成一条转发的规则。包含:ID、目标URL、Predicate集合以及Filter集合
  • Predicate(谓词)
    即java.util.function.Predicate,Spring Cloud Gateway使用Predicate实现路由的匹配条件
  • Filter(过滤器)
    修改请求以及响应
    练习Spring Cloud Alibaba 6 ——Spring Cloud Gateway_第2张图片

3.Spring Cloud Gateway-路由谓词

Spring Cloud Gateway中内置的谓词工厂,包括:After、Before、Between、Cookie、Header、Host、Method、Path、Query、RemoteAddr

路由配置的两种形式
路由到指定URL
  • 通配:表示访问 GATEWAY_URL/** 会转发到 http://www.xxxx.com/**
spring:
  cloud:
    gateway:
      routes:
      - id: {唯一标识}
        uri: http://www.xxxx.com
  • 精确匹配:表示访问 GATEWAY_URL/spring-cloud-getway/get/ 会转发到 http://www.xxxx.com/spring-cloud-getway/get/
spring:
  cloud:
    gateway:
      routes:
      - id: {唯一标识}
        uri: http://www.xxxx.com/spring-cloud-getway/get/
路由到服务发现组件上的微服务

通配:表示访问 GATEWAY_URL/** 会转发到 user-center 微服务的 /**

spring:
  cloud:
    gateway:
      routes:
      - id: {唯一标识}
        uri: lb://user-center

精确匹配:表示访问 GATEWAY_URL/users/1 会转发到 user-center 微服务的 /users/1

spring:
  cloud:
    gateway:
      routes:
      - id: {唯一标识}
        uri: lb://user-center/users/1

4.自定义路由谓词

修改gateway的配置

测试:设置早上九点到晚上九点允许访问

gateway:
      discovery:
        locator:
          # 让gateway通过服务发现组件找到其他的微服务
          enabled: true
      routes:
      - id: user_route
        uri: lb://user-center-kk
        predicates:
        - BetweenTime=上午9:00,下午9:00
添加BetweenTimeRoutePredicateFactory类继承AbstractRoutePredicateFactory类
@Component
@Slf4j
public class BetweenTimeRoutePredicateFactory extends AbstractRoutePredicateFactory<BetweenTimeConfig> {
    public BetweenTimeRoutePredicateFactory() {
        super(BetweenTimeConfig.class);
    }

    @Override
    public Predicate<ServerWebExchange> apply(BetweenTimeConfig config) {

        LocalTime start = config.getStart();
        LocalTime end = config.getEnd();
        return exchange -> {
            log.info("起始时间:{}",start);
            LocalTime now = LocalTime.now();
            return now.isAfter(start) && now.isBefore(end);
        };
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("start", "end");
    }
}
添加BetweenTimeConfig类
@Data
public class BetweenTimeConfig {
    private LocalTime start;
    private LocalTime end;
}
启动项目测试

当前时间在范围内时
练习Spring Cloud Alibaba 6 ——Spring Cloud Gateway_第3张图片
当前时间不在范围内时
练习Spring Cloud Alibaba 6 ——Spring Cloud Gateway_第4张图片

5.Spring Cloud Gateway-过滤器

Spring Cloud Gateway内置的Filter工厂

1 AddRequestHeader GatewayFilter Factory
2 AddRequestParameter GatewayFilter Factory
3 AddResponseHeader GatewayFilter Factory
4 DedupeResponseHeader GatewayFilter Factory
5 Hystrix GatewayFilter Factory
6 FallbackHeaders GatewayFilter Factory
7 PrefixPath GatewayFilter Factory
8 PreserveHostHeader GatewayFilter Factory
9 RequestRateLimiter GatewayFilter Factory
10 RedirectTo GatewayFilter Factory
11 RemoveHopByHopHeadersFilter GatewayFilter Factory
12 RemoveRequestHeader GatewayFilter Factory
13 RemoveResponseHeader GatewayFilter Factory
14 RewritePath GatewayFilter Factory
15 RewriteResponseHeader GatewayFilter Factory
16 SaveSession GatewayFilter Factory
17 SecureHeaders GatewayFilter Factory
18 SetPath GatewayFilter Factory
19 SetResponseHeader GatewayFilter Factory
20 SetStatus GatewayFilter Factory
21 StripPrefix GatewayFilter Factory
22 Retry GatewayFilter Factory
23 RequestSize GatewayFilter Factory
24 Modify Request Body GatewayFilter Factory
25 Modify Response Body GatewayFilter Factory
26 Default Filters

配置示例
spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: https://example.org
        filters:
        - AddRequestHeader=X-Request-Foo, Bar 

6.自定义过滤器

自定义过滤器工厂的两种方式
  • 继承AbstractGatewayFilterFactory,配置示例如下
    练习Spring Cloud Alibaba 6 ——Spring Cloud Gateway_第5张图片
  • 继承AbstractNameValueGatewayFilterFactory,配置示例如下
    练习Spring Cloud Alibaba 6 ——Spring Cloud Gateway_第6张图片
自定义过滤器的核心API
  • exchange.getRequest().mutate.xxx //修改request
  • exchange.mutate().xxx // 修改exchange
  • chain.filter(exchange) //传递给下一个过滤器处理
  • exchange.getResponse() //拿到响应
修改gateway的配置
gateway:
      discovery:
        locator:
          # 让gateway通过服务发现组件找到其他的微服务
          enabled: true
      routes:
      - id: user_route
        uri: lb://user-center-kk
        predicates:
        - BetweenTime=上午9:00,下午11:50
        filters:
        - AddResponseHeader=X-Response-Foo, Bar
        - PreLog=a,b
添加PreLogGatewayFilterFactory类继承AbstractNameValueGatewayFilterFactory类
@Slf4j
@Component
public class PreLogGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
    @Override
    public GatewayFilter apply(NameValueConfig config) {
        return ((exchange, chain) -> {
            log.info("请求进来了...{},{}", config.getName(), config.getValue());
            ServerHttpRequest modifiedRequest = exchange.getRequest()
                    .mutate()
                    .build();
            ServerWebExchange modifiedExchange = exchange.mutate()
                    .request(modifiedRequest)
                    .build();

            return chain.filter(modifiedExchange);
        });
    }
}
启动项目测试

在这里插入图片描述

7.全局过滤器

GlobalFilter 接口和 GatewayFilter 有一样的接口定义,只不过, GlobalFilter 会作用于

当请求到来时,Filtering Web Handler 处理器会添加所有 GlobalFilter 实例和匹配的 GatewayFilter 实例到过滤器链中。

过滤器链会使用 org.springframework.core.Ordered 注解所指定的顺序,进行排序。Spring Cloud Gateway区分了过滤器逻辑执行的”pre”和”post”阶段,所以优先级高的过滤器将会在pre阶段最先执行,优先级最低的过滤器则在post阶段最后执行。

注意: @Order(x)里的x的数值越小越靠前执行。

@Bean
@Order(-1)
public GlobalFilter a() {
    return (exchange, chain) -> {
        log.info("first pre filter");
        return chain.filter(exchange).then(Mono.fromRunnable(() -> {
            log.info("third post filter");
        }));
    };
}

@Bean
@Order(0)
public GlobalFilter b() {
    return (exchange, chain) -> {
        log.info("second pre filter");
        return chain.filter(exchange).then(Mono.fromRunnable(() -> {
            log.info("second post filter");
        }));
    };
} 

7.Spring Cloud Gateway——监控

只要为Spring Cloud Gateway添加Spring Boot Actuator( spring-boot-starter-actuator )的依赖,并将 gateway 端点暴露,即可获得若干监控端点,监控 & 操作Spring Cloud Gateway的方方面面。

management:
  endpoints:
    web:
      exposure:
        # 暴露gateway 端点
        include: gateway 

未完待续!!!

上一篇: 练习Spring Cloud Alibaba —— 5.
下一篇: 练习Spring Cloud Alibaba —— 7.

你可能感兴趣的:(练习Spring Cloud Alibaba 6 ——Spring Cloud Gateway)