Gateway
目录
- Gateway
- 一、为什么需要网关
- 二、gateway入门
- 三、断言工厂
- 四、过滤器工厂
- 五、全局过滤
- 1. 实现
- 2. 过滤器执行顺序
 
- 六、跨域问题
 
一、为什么需要网关
不能让外部能够直接访问微服务,而是需要通过网关访问:

网关的作用:
- 身份认证和权限校验
- 请求路由,负载均衡
- 限流
二、gateway入门
搭建网关步骤:
-  创建新的模块,引入依赖: <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>
-  配置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
-  启动测试:   
-  小结:  
三、断言工厂
我们配置时候配置的路由断言就是由断言工厂解析的,我们配置的是字符串,路由工厂则取解析。

配一个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();
    }
}
这里有个小坑:
如果这个全局过滤器没有放在和启动类同包下,那么无法被扫描,也就无法生效,解决方案也很简单:
- 放在和启动类同包下
- 使用@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 # 本次跨域有效期



















