Spring Cloud Gateway(黑马springcloud笔记)

2023-05-16

Gateway

目录

  • Gateway
    • 一、为什么需要网关
    • 二、gateway入门
    • 三、断言工厂
    • 四、过滤器工厂
    • 五、全局过滤
      • 1. 实现
      • 2. 过滤器执行顺序
    • 六、跨域问题

一、为什么需要网关

不能让外部能够直接访问微服务,而是需要通过网关访问:

在这里插入图片描述

网关的作用:

  • 身份认证和权限校验
  • 请求路由,负载均衡
  • 限流

二、gateway入门

搭建网关步骤:

  1. 创建新的模块,引入依赖:

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    
  2. 配置nacos和路由

    spring:
      cloud:
        nacos:
          server-addr: localhost:80
        gateway:
          routes:
            -
              id: user-service # 路由id 必填 不重复即可
              uri: lb://userService # 路由目标地址
              predicates: # 路由断言,判断请求是否符合规则
                - 'Path=/user/**' # 判断路径是否以/user开头,如果是则符合
            -
              id: order-service
              uri: lb://orderService
              predicates:
                - 'Path=/order/**'
      application:
        name: gateway
    
    server:
      port: 10010
    
  3. 启动测试:

    在这里插入图片描述

    在这里插入图片描述

  4. 小结:

    在这里插入图片描述

三、断言工厂

我们配置时候配置的路由断言就是由断言工厂解析的,我们配置的是字符串,路由工厂则取解析。

在这里插入图片描述

配一个after试试:


spring:
  cloud:
    nacos:
      server-addr: localhost:80
    gateway:
      routes:
        -
          id: user-service # 路由id 必填 不重复即可
          uri: lb://userService # 路由目标地址
          predicates: # 路由断言,判断请求是否符合规则
            - 'Path=/user/**' # 判断路径是否以/user开头,如果是则符合
        -
          id: order-service
          uri: lb://orderService
          predicates:
            - 'Path=/order/**'
            - After=2023-01-14T23:38:47.789+08:00[Asia/Shanghai]
  application:
    name: gateway

server:
  port: 10010

改着玩,如果符合要求就能请求成功,如果不符合要求就404了。

四、过滤器工厂

可对进入网关的请求和服务的响应作处理。

在这里插入图片描述

局部配置:


spring:
  cloud:
    nacos:
      server-addr: localhost:80
    gateway:
      routes:
        -
          id: user-service # 路由id 必填 不重复即可
          uri: lb://userService # 路由目标地址
          predicates: # 路由断言,判断请求是否符合规则
            - 'Path=/user/**' # 判断路径是否以/user开头,如果是则符合
          filters:
            - AddRequestHeader=IHeader,this is filter
        -
          id: order-service
          uri: lb://orderService
          predicates:
            - 'Path=/order/**'
            - After=2023-01-14T23:40:00+08:00[Asia/Shanghai]
  application:
    name: gateway

server:
  port: 10010

修改user-service的代码:

@GetMapping("/{id}")
public User queryById(@PathVariable("id") Long id,
                      @RequestHeader(value = "IHeader", required = false) String IHeader) {
    System.out.println(IHeader);
    return userService.queryById(id);

}

访问user-service的接口即可看到打印 this is filter

全局配置:

spring:
  cloud:
    nacos:
      server-addr: localhost:80
    gateway:
      routes:
        -
          id: user-service # 路由id 必填 不重复即可
          uri: lb://userService # 路由目标地址
          predicates: # 路由断言,判断请求是否符合规则
            - 'Path=/user/**' # 判断路径是否以/user开头,如果是则符合
        -
          id: order-service
          uri: lb://orderService
          predicates:
            - 'Path=/order/**'
            - After=2023-01-14T23:40:00+08:00[Asia/Shanghai]
      default-filters:
       - AddRequestHeader=IHeader,this is filter
  application:
    name: gateway

server:
  port: 10010

访问user-service的接口即可看到打印 this is filter

五、全局过滤

1. 实现

和上一种配置的过滤器一样,区别在于全局过滤器可以自定义逻辑。

实现GlobalFilter接口即可(有web Flux的感觉)

public class IFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        return null;
    }
}

例子:

// 过滤器链上的优先级 越低优先级越高
@Order(-1)
@Component
public class IFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 1.获取请求参数
        ServerHttpRequest request = exchange.getRequest();
        MultiValueMap<String, String> queryParams = request.getQueryParams();
        // 2.获取某个参数
        String auth = queryParams.getFirst("username");
        // 3.业务
        if ("admin".equals(auth)) {
            // 放行
            return chain.filter(exchange);
        }
        // 修改返回状态码
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        // 拦截
        return exchange.getResponse().setComplete();
    }
}

这里有个小坑:

如果这个全局过滤器没有放在和启动类同包下,那么无法被扫描,也就无法生效,解决方案也很简单:

  1. 放在和启动类同包下
  2. 使用@ComponentScan、@Import等注解,将其导入IOC容器中。

2. 过滤器执行顺序

不管是yml中配置的filters、default-filters还是GlobalFilter,其本质都是GatewayFilter。

所以他们的执行顺序是由他们的order值决定,他们的order值有以下规则:

  • 路由过滤器和默认过滤器的order由spring指定,默认是按照声明顺序从1递增
  • GlobalFilter的Order值由我们决定
  • 当过滤器的order值相同时,会按照defaultFilter > 路由过滤器 > GlobalFilter的顺序执行

六、跨域问题

经典问题,配置解决即可

spring:
  cloud:
    gateway:
      globalcors:
        corsConfigurations:
          '[/**]':
            # 允许跨域的源(网站域名/ip),设置*为全部
            allowedOrigins: "*"
            # 允许跨域的method, 默认为GET和OPTIONS,设置*为全部
            allowedMethods: "*"
            # 允许跨域请求里的head字段,设置*为全部
            allowedHeaders: "*"
            allowCredentials: true # 是否允许携带cookie
            maxAge: 360000 # 本次跨域有效期
         allowedOrigins: "*"
            # 允许跨域的method, 默认为GET和OPTIONS,设置*为全部
            allowedMethods: "*"
            # 允许跨域请求里的head字段,设置*为全部
            allowedHeaders: "*"
            allowCredentials: true # 是否允许携带cookie
            maxAge: 360000 # 本次跨域有效期
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring Cloud Gateway(黑马springcloud笔记) 的相关文章

随机推荐