6. 微服务之Gateway网关

本文介绍了Spring Cloud Gateway作为微服务网关的作用,包括身份验证、路由到微服务和流量限制。详细阐述了搭建网关服务的步骤,配置路由、路由断言工厂和过滤器的使用,如PathRoutePredicateFactory、AddRequestHeader等。此外,还讲解了全局过滤器的实现和过滤器执行顺序。最后提到了CORS跨域配置的解决策略,确保前后端交互的顺利进行。
摘要由CSDN通过智能技术生成
6.1 网关的作用

在这里插入图片描述

  1. 对用户请求做身份认证、权限校验
  2. 将用户请求路由到微服务,并实现负载均衡
  3. 对用户请求做限流
6.2 搭建网关服务步骤

创建一个新的模块作为网关系统,在 pom.xml 中引入 SpringCloudGateway 的依赖,同时还要引入 nacos 的服务发现依赖

<!--nacos服务注册发现依赖-->
<dependency>
     <groupId>com.alibaba.cloud</groupId>
     <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
 </dependency>
 <!--网关依赖-->
 <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-gateway</artifactId>
 </dependency>

在application.yml配置文件中编写路由配置及nacos地址

server:
  port: 10010
spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 网关路由配置
        - id: user-service # 路由标识,必须唯一
          uri: lb://user-service # 路由的目标地址,lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,判断请求是否符合规则
            - Path=/user/** # 路径匹配,判断路径是否是以/user/开头,如果是则符合
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/order/**
大致流程:

在这里插入图片描述

路由配置大致包括:

  1. 路由id:路由的唯一标识
  2. 路由目标(uri):路由的目标地址,http代表固定地址,lb代表根据服务名负载均衡
  3. 路由断言(predicates):判断路由的规则
  4. 路由过滤器(filters):对请求或响应做处理
6.3 路由断言工厂(路由匹配规则)

我们在配置文件中写的断言规则只是字符串,这些字符串会被Predicate Factory 读取并处理,转变为路由判断的条件
例如 Path=/user/** 是按照路径匹配,这个规则是由 PathRoutePredicateFactory 类来处理的

在这里插入图片描述
具体规则的使用,可以参考Spring官网 https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories

6.4 路由过滤器

GatewayFilter 是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理

在这里插入图片描述
Spring提供了30多种过滤器:

  • AddRequestHeader:此列表将 X-Request-red:blue 添加到所有匹配请求的下游请求头

    spring:
      cloud:
        gateway:
          routes:
          - id: add_request_header_route
            uri: https://example.org
            # 过滤器
            filters:
            - AddRequestHeader=X-Request-red, blue
    
  • AddRequestParameter:为所有匹配请求的下游请求的地址添加请求参数 /?red=blue

    spring:
      cloud:
        gateway:
          routes:
          - id: add_request_parameter_route
            uri: https://example.org
            filters:
            - AddRequestParameter=red, blue
    
  • AddResponseHeader:此列表将 X-Request-red:blue 添加到所有匹配请求的下游请求头

    spring:
      cloud:
        gateway:
          routes:
          - id: add_response_header_route
            uri: https://example.org
            filters:
            - AddResponseHeader=X-Response-Red, Blue
    
  • PrefixPath:将 /mypath 作为前缀添加到路径,所以例如 /hello 的路径将会变为 /mypath/hello

    spring:
      cloud:
        gateway:
          routes:
          - id: prefixpath_route
            uri: https://example.org
            filters:
            - PrefixPath=/mypath
    
  • RemoveRequestHeader:在将 X-Request-Foo 标头发送到下游之前将其删除

    spring:
      cloud:
        gateway:
          routes:
          - id: removerequestheader_route
            uri: https://example.org
            filters:
            - RemoveRequestHeader=X-Request-Foo
    
  • RemoveResponseHeader:在将 X-Response-Foo 头返回到网关客户端之前从响应中删除该头

    spring:
      cloud:
        gateway:
          routes:
          - id: removeresponseheader_route
            uri: https://example.org
            filters:
            - RemoveResponseHeader=X-Response-Foo
    
  • RemoveRequestParameter:在向下游发送之前删除 red 参数

    spring:
      cloud:
        gateway:
          routes:
          - id: removerequestparameter_route
            uri: https://example.org
            filters:
            - RemoveRequestParameter=red
    

部分过滤器中参数可以用变量来代替,可以解析出匹配路径或主机的URI变量
例如:

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: https://example.org
        predicates:
        - Path=/red/{segment}
        filters:
        - AddRequestHeader=X-Request-Red, Blue-{segment}

具体可以看Spring官网:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories

默认过滤器 - default-filters

可以对所有路由都生效,而不是针对单个路由

spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 网关路由配置
        - id: user-service # 路由标识,必须唯一
          uri: lb://user-service # 路由的目标地址,lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,判断请求是否符合规则
            - Path=/user/** # 路径匹配,判断路径是否是以/user/开头,如果是则符合
          filters:
            # 添加请求参数
            - AddRequestParameter=red, blue
            # 添加请求头
            - AddRequestHeader=X-Request-red, blue
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/order/**
      # 默认过滤器
      default-filters:
        # 添加响应头
        - AddResponseHeader=X-Response-Red, Blue 
6.5 全局过滤器 - GlobalFilter

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

定义方式:创建一个拦截器实现 GlobalFilter 接口
例子:判断请求参数是否携带authorization参数,携带放行,否则拦截

// 顺序注解,和实现Ordered接口效果相同
// @Order(-1)
@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {
    /**
     * 处理当前请求,有必要的话通过{@link GatewayFilterChain} 将请求交给下一个过滤器处理
     * @param exchange 请求上下文,里面可以获取 Request、Response等信息
     * @param chain 用来把请求委托给下一个过滤器
     * @return {@code Mono<Void>} 返回表示当前过滤器业务结束
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 1. 获取请求参数
        ServerHttpRequest request = exchange.getRequest();
        MultiValueMap<String, String> params = request.getQueryParams();
        // 2. 获取参数中的 authorization 参数
        String auth = params.getFirst("authorization");
        // 3. 判断参数值是否存在
        if (auth != null && auth != "") {
            // 4. 是,放行
            return chain.filter(exchange);
        }
        // 5. 否,拦截
        // 5.1. 设置状态码
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        // 5.2 拦截请求
        return exchange.getResponse().setComplete();
    }

    /**
     *  该过滤器的优先级,越小优先级越高
     * @return int级别
     */
    @Override
    public int getOrder() {
        return -1;
    }
}
6.6 过滤器链执行顺序

请求进入网关会碰到三类过滤器:当前路由的过滤器(具体服务下)、DefaultFilter(默认过滤器)、GlobalFilter(全局过滤器)
请求路由后,会将当前路由过滤器和DefaultFilter、GlobalFilter,合并到一个过滤器链(集合)中,排序后依次执行每个过滤器

具体顺序:
  • 每一个过滤器都必须指定一个 int 类型的 order 值,order值越小,优先级越高,执行顺序越靠前
  • GlobalFilter 通过实现 Ordered 接口,或者添加 @Order 注解来指定 order 值,自己设定
  • 路由过滤器 和 DefaultFilter 的 order 由 Spring 指定,默认是按照声明顺序从 1 递增
  • 当过滤器的 order 值一样时,会按照 DefaultFilter > 路由过滤器 > GlobalFilter 的顺序执行
6.7 网关的cors跨域配置
跨域问题:

当发起者与服务端所在域不一致时就是跨域,其中 协议、域名、端口,有一样不同则视为跨域,而当前后端分离,前端用ajax发起请求到后端时,此时因为域的不同浏览器会拦截该请求

解决方案:CORS

即在前端发起ajax请求进行跨域访问服务端时,浏览器先会询问服务端是否允许请求者的访问,服务端会给浏览器一个通行证使浏览器放行该请求

具体配置
spring:
  cloud:
    gateway:
      globalcors: # 全局跨域处理
        # 浏览器会先询问是否允许跨域,该配置使浏览器cors询问options正常发起
        add-to-simple-url-handler-mapping: true
        cors-configurations:
          '[/**]':
            allowedOrigins: # 允许哪些网站的跨域请求
              - "http://localhost:8090"
              - "http://www.leyou.com"
            allowedMethods: # 允许的跨域ajax的请求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: # 允许在请求中携带的头信息
              - "*"
            allowCredentials: true # 是否允许携带Cookie
            # 减少cors询问损耗,在有效期内浏览器将不会重复询问是否允许跨域
            maxAge: 360000
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值