Spring Cloud Gateway 原理与应用场景

导读:本篇文章讲解 Spring Cloud Gateway 原理与应用场景,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com


why 为什么需要网关?

在这里插入图片描述
如图可知:

  • 在常规没有网关的情况下,无法对多个服务进行统一的处理,比如我需要做统一的鉴权,这时候需要在每个服务上增加鉴权功能来达到目的,工作量大且不好维护
  • 在有网关的情况下,可以将所有的流量都达到网关,然后通过网关来对请求做统一的鉴权处理,非常方便

what 网关的应用场景

  1. 降低复杂性,如前台请求多个服务,可以通过网关进行简化

  2. 鉴权(网关中重点):用户是否合法?有哪些权限可以请求哪些服务在这里插入图片描述

  3. 安全性:登录态鉴权,如果鉴权不通过,直接被打回去

  4. 多协议适配,可以针对后端多种不同的协议,在网关层统一处理以后以HTTP对外提供服务,其实就是起到一个适配器的作用

  5. 限流:网络限流,保证后台服务稳定运行

  6. 缓存:在网关层统一缓存,如登录态、鉴权信息

  7. 流量调配:灰度发布(金丝雀发布 / A/B Test),在部署上线新版本的时候,可以通过网关来让部分流量使用新服务,部分流量保持旧服务,有问题可以及时的回滚,让影响面最小在这里插入图片描述

  8. 统一处理:提供统一的错误码、状态码等

  9. 请求转发:并且可以基于网关实现内网与外网的隔离

常见网关实现方案对比

Spring Cloud Gateway

  • Spring Cloud Gateway是Spring官方团队研发的API网关技术, 它的目的是取代Zuul为微服务提供一个简单高效的API网关。
  • Zuul 1.x采用的是传统的thread per connection方式来处理请求,也就是针对每一个请求,会为这个请求专门分配一个线程来进行处理, 直到这个请求完成之后才会释放线程,一旦后台服务器响应较慢,就会使得该线程被阻塞,所以它的性能不好
  • Zuul本身存在的一些性能问题不适合于高并发的场景,虽然后来Netflix决定开发高性能版Zuul 2.x,但是Zuul 2.x的发布时间一直不确定。 虽然Zuul 2.x后来已经发布并且开源了,但是Spring Cloud并没有打算集成进来。
  • Spring Cloud Gateway是依赖于Spring Boot 2.0Spring WebFluxProject Reactor等技术开发的网关,它不仅提供了统一的路由请求的方式, 还基于过滤链的方式提供了网关最基本的功能。

Zuul

Zuul是Netflix开源的微服务网关
在这里插入图片描述
Zuul的核心都是Filter组成,它定义了4中标准的类型过滤器,Pre FiltersRouting FiltersPost FiltersError Filters,这些会对应请求的整个生命周期

OpenResty

OpenResty本质就是由Nginx+Lua集成的一个高性能Web应用服务器,内部集成了大量Lua库和第三方模块
在这里插入图片描述
OpenResty将请求分为多个阶段,可以在不同的阶段挂载Lua脚本来实现不同阶段的自定义行为
OpenResty实现网关功能的核心就是在图中的11个步骤中挂载Lua脚本来实现功能的扩展

网关方案总结

网关 限流 鉴权 监控 易用性 可维护性 成熟度
Spring Cloud Gateway 可以通过ip、用户进行集群限流,提供扩展接口 普通鉴权、Auth2.0 Gateway Metrics Filter 简单易用 Spring系列下的,可扩展性高、易配置、可维护性好 Spring Cloud社区程数,但Gateway资源较少
Zuul2.x 通过配置文件配置对集群限流和单服务限流可通过filter实现限流扩展 filter中实现 filter中实现 参考资料少 可维护性差 开源不久,资料少
OpenResty 需使用lua开发实现 需使用lua开发实现 需要开发 简单易用,但需要lua开发的很多 可维护性差,将需要维护大量lua库 很成熟,资料多
Kong 根据时间单位限流、用户限流,可以在源码上二次开发 普通鉴权、Key Auth、HMAC、Auth2.0 可上报datadog,记录请求数、请求数据量、应答数据量、接收与发送时间间隔、状态码数量、kong内运行时间 简单易用,api转发通过管理员接口配置,开发需使用lua脚本 可维护性较差,将需要维护大量lua脚本 相对成熟,开源

除此之外,还有Tyk、Apisix、Orange

Gateway架构原理

如下图所示:Gateway处理一个请求的过程
在这里插入图片描述

  1. 客户端发起一个请求到gateway
  2. 通过Netty Server来处理请求
  3. 【关键】会根据Predicate(谓词)、Filter判断该走哪个路由
  4. 通过Netty Proxy代理来向微服务发起请求

图中关键点在于 Predicate和Filters,它们都有对应的工厂类

RoutePredicateFactory

RoutePredicateFactory:路由谓词工厂,比如日期、cookie、header、host、predicate、method等属性进行路由

Predicate可以通过HTTP请求的属性进行匹配
在这里插入图片描述

  • BeforeRoutePredicateFactory——请求在指定日期之前
    #【指定时间规则匹配路由】
    #在2022-01-01 00:00:00之前访问的请求,都会转到http://localhost:8080,即:http://localhost:8088/say会转发到http://localhost:8080/say
    spring:
      cloud:
        gateway:
          routes:
            - id: before_route
              uri: http://localhost:8080
              predicates:
                - Before=2022-01-01T00:00:00.000+08:00
    
  • AfterRoutePredicateFactory——请求在指定日期之后
    #【指定时间规则匹配路由】
    #在2021-01-01 00:00:00之后访问的请求,都会转到http://localhost:8080,即:http://localhost:8088/say会转发到http://localhost:8080/say
    spring:
      cloud:
        gateway:
          routes:
            - id: after_route
              uri: http://localhost:8080
              predicates:
                - After=2021-01-01T00:00:00.000+08:00
    
  • CookieRoutePredicateFactory——请求中携带的Cookie是否匹配配置的规则
    #【指定Cookie规则匹配路由】
    #请求配置localhost的Cookie(chocolate=mic;) 请求http://localhost:8088/say会转发到http://localhost:8080/say
    spring:
      cloud:
        gateway:
          routes:
            - id: cookie_route
              uri: http://localhost:8080
              predicates:
                - Cookie=chocolate, mic
    
  • HeaderRoutePredicateFactory——请求中Header头消息对应的name和value与Predicate配置的值是否匹配
    #【指定Header规则匹配路由】
    #请求配置Header(key=X-Request-Id value=1) 请求http://localhost:8088/say会转发到http://localhost:8080/say
    spring:
      cloud:
        gateway:
          routes:
            - id: header_route
              uri: http://localhost:8080
              predicates:
                - Header=X-Request-Id, \d+
    
  • HostRoutePredicateFactory——匹配请求中的Host字段进行路由
    #【指定Host规则匹配路由】
    #请求配置Header(Host:www.muse.com) 请求http://localhost:8088/say会转发到http://localhost:8080/say
    spring:
      cloud:
        gateway:
          routes:
            - id: host_route
              uri: http://localhost:8080
              predicates:
                - Host=**.muse.com
    
  • MethodRoutePredicateFactory——根据HTTP请求的Method属性来匹配以实现路由
    #【请求方法匹配路由】
    # 请求POST http://localhost:8088/shout会转发http://localhost:8080/shout。请求GET http://localhost:8088/say 会报"404 Not Found"
    spring:
      cloud:
        gateway:
          routes:
            - id: method_route
              uri: http://localhost:8080 #访问地址
              predicates:
                - Method=POST
    
  • PathRoutePredicateFactory——根据请求路径匹配Predicate配置来进行请求路由
    #【请求路径匹配路由】
    # 请求POST http://localhost:8088/gateway/say会转发http://localhost:8080/say。
    spring:
      cloud:
        gateway:
          routes:
            - id: path_routeHeaderRoutePredicateFactory
              uri: http://localhost:8080 #访问地址
              predicates:
                - Path=/gateway/** #路径匹配
              filters:
                - StripPrefix=1 #跳过前缀
    

RouteFilterFactory

RouteFilterFactory:路由过滤器,比如添加reqeust参数、添加header、限流,类似于spring中的fiter

在这里插入图片描述
Filter主要分为两种类型:

  1. Pre类型过滤器
  2. Post类型过滤器

Filter实现方式主要由两种:

  1. GatewayFilter只会应用到单个路由或一个分组的路由上
  2. GlobalFilter会应用到所有的路由上

可用过滤器说明:

  • AddRequestParameterGatewayFilterFactory——该过滤器的功能是对所有匹配的request请求中添加一个查询参数
    #【添加request查询参数过滤器】
    #会对所有请求增加teacher=muse这个参数
    spring:
      cloud:
        gateway:
          routes:
            - id: add_request_parameter_route
              uri: http://localhost:8080 #访问地址
              predicates:
                - Path=/**
              filters:
                - AddRequestParameter=teacher, muse
    
  • AddResponseHeaderGatewayFilterFactory——该过滤器会对所有匹配的请求, 在返回结果给客户端之前, 在Header中添加相应的数据
    #【添加response响应Header参数过滤器】
    #返回结果给客户端之前,在Header中添加相应的数据
    spring:
      cloud:
        gateway:
          routes:
            - id: add_response_header_route
              uri: http://localhost:8080 #访问地址
              predicates:
                - Path=/**
              filters:
                - AddResponseHeader=X-Response-Teacher, Muse
    
  • RequestRateLimiterGatewayFilterFactory——该过滤器会对访问到当前网关的所有请求执行限流过滤
    #【添加限流过滤器】
    spring:
      cloud:
        gateway:
          routes:
            - id: request_ratelimiter_route
              uri: http://localhost:8080 #访问地址
              predicates:
                - Path=/**
              filters:
                - name: RequestRateLimiter
                  args:
                    redis-rate-limiter.replenishRate: 1 #令牌桶中令牌的填充速度,代表允许每秒执行的请求数
                    redis-rate-limiter.burstCapacity: 1 #令牌桶的容量,也就是令牌桶最多能够容纳的令牌数。表示每秒用户最大能够执行的请求数量
    
  • RetryGatewayFilterFactory——请求重试过滤器, 证据指定的触发条件, 发起重试操作
    #【添加请求重试过滤器】
    spring:
      cloud:
        gateway:
          routes:
            - id: retry_route
              uri: http://localhost:8080
              predicates:
                - Path=/example/**
              filters:
                - name: Retry
                  args:
                    retries: 3 #请求重试次数,默认值是3
                    status: 500 #HTTP请求返回的状态码,针对指定状态码进行重试。
                - StripPrefix=1
    
  • GatewayMetricsFilter——网关指标过滤器, 这个过滤器会添加name=gateway.requests的timer metrics
    #【网关指标过滤器——GatewayMetricsFilter】
    management:
      endpoint:
        gateway:
          enabled: true
      endpoints:
        web:
          exposure:
            include: "*"
    
  • 自定义过滤器——GatewayFilter和GlobalFilter
    #【请求路径匹配路由——配置自定义过滤器】
    spring:
      cloud:
        gateway:
          routes:
            - id: define_filter
              uri: http://localhost:8080 #访问地址
              predicates:
                - Path=/gateway/** #路径匹配
              filters:
                - name: GpDefine #自定义过滤器的名字,即:GpDefineGatewayFilterFactory
                  args:
                    name: Gp_Mic #GpConfig.getName这个值
                - StripPrefix=1 #跳过前缀
    

Gateway集成Nacos实现请求负载

具体实现架构如下图
在这里插入图片描述

Gateway集成Sentinel实现网关限流

在这里插入图片描述

总结

通过对比多种网关的实现方案,我们可以根据实际业务与各个方案特点进行选型;
重点介绍了Gateway的基本原理,实际应用场景,如鉴权、请求负载、限流等

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/17817.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!