Spring Cloud Gateway(黑马springcloud笔记)

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

Gateway

目录

一、为什么需要网关

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

在这里插入图片描述

网关的作用

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

二、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 # 本次跨域有效期
阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Spring