统一网关Gateway(未完待续)

123 阅读3分钟

Spring Cloud Gateway的核心概念

路由(Route)

路由是Spring Cloud Gateway的基本构建块,每个路由包含以下信息:

  • ID:唯一标识路由的字符串
  • URI:目标服务的URI,通常是一个HTTP或HTTPS地址,或者是lb://微服务名称
  • Predicates:一组断言,用于判断请求是否匹配当前路由。
  • Filters:一组过滤器,用于在路由请求之前或之后对请求和响应进行处理。

断言(Predicate)

断言用于判断请求是否符合条件,常见的断言包括:

  • Path:基于请求路径进行匹配。
  • Header:基于请求投进行匹配。
  • Method:基于HTTP方法(如GET、POST)进行匹配。
  • Query:基于请求参数进行匹配。

过滤器(Filter)

过滤器用于在请求被路由之前或之后进行处理。常见的过滤器包括:

  • AddRequestHeader:在请求头中添加新的键值对。
  • AddResponseHeader:在响应头中添加新的键值对。
  • StripPrefix:移除请求路径中的前缀。
  • RateLimiter:对请求进行限流控制。

过滤器有三种(当前路由的过滤器、DefaultFilter、GlobalFilter)

  1. 当前路由的过滤器

    下面的示例配置中的filter就是当前路由的过滤器。

    作用:配置在路由下的过滤器只对当前路由的请求生效。

  2. 默认过滤器

    作用:对所有路由都生效的过滤器。

spring:
    cloud:
        gateway:
            routes:
                - id: hello
                   uri: lb://helloworld
            default-filters: #默认过滤器,会对所有的路由请求都生效
            - AddRequestHeader=hello, HelloWorld! #添加请求头
            
  1. 全局过滤器 GlobalFilter

    全局过滤器的作用也是处理一切进入网关的请求和微服务响应,与GatewayFilter的作用一样。区别在于GatewayFilter通过配置定义,处理逻辑是固定的。而GlobalFilter的逻辑需要自己写代码实现。

    定义全局过滤器的方式是实现GlobalFilter接口。

    public interface GlobalFilter{
        /**
        * 处理当前请求,有必要的话通过{@link GatewayFilterChain}将请求交给下一个过滤器处理
        * @param exchange 请求上下文,里面可以获取Request、Response等信息
        * @param chain 用来把请求委托给下一个过滤器
        * @return {@code Mono<Void>} 返回表示当前过滤器业务结束。
        */
        Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);    
    }
    

    实现全局过滤器的步骤?

    1. 实现GlobalFilter接口
    2. 添加@Order注解或实现Ordered接口
    3. 编写处理逻辑

过滤器执行顺序

  1. 首先根据order值来判断,order值越小,优先级越高。
  2. 当order值一样时,顺序是defaultFilter最先,然后是局部的路由过滤器,最后是全局过滤器。

示例配置

server:
    port: 10010 #网关端口
spring:
    application:
        name: gateway # 服务名称
    cloud:
        nacos:
            server_addr: localhost:8848 # nacos地址
        gateway:
            routes: # 网关路由配置
                -id: user-service #路由id,自定义,只要唯一即可
                # uri: https://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
                 uri: lb://service # 路由的目标地址 lb就是负载均衡,后面跟服务名称
                 predicates: #路由断言,也就是判断请求是否符合路由规则的条件
                     - Path=/hello/** # 这个是按照路径匹配,只要以/user/开头就符合要求
                 filters:
                     - AddRequestHeader=Blue, Red
                     

注意:创建网关的时候,需要引入nacos服务发现和gateway依赖,这样路由才能拉取到nacos上注册的相关服务。

跨域问题处理

跨域:域名不一致就是跨域,主要包括:

跨域问题:浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截的问题

解决方案:CORS

配置示例

spring:
    cloud:
        gateway:
            globalcors: #全局的跨域处理
                add-to-simple-url-handler-mapping: true #解决options请求被拦截问题
                corsConfigurations:
                '[/**]':
                   allowedOrigins: # 允许哪些网站的跨域请求
                - "http://localhost:8090"
                   allowedMethods: #允许的跨域ajax的请求方式
                - "GET"
                    - "POST"
                    - "DELETE"
                    - "PUT"
                    - "OPTIONS"
                    allowedHeaders: "*" # 允许在请求中携带的头信息
                 allowCredentials: true #是否允许携带cookie
                     maxAge: 360000 #这次跨域检测的有效期