API网关:SpringCloud GateWay

一. 网关的作用及背景

1.API网关的作用
  • 请求路由

在我们的系统中由于同一个接口新老两套系统都在使用,我们需要根据请求上下文将请求路由到对应的接口。

  • 统一鉴权

对于鉴权操作不涉及到业务逻辑,那么可以在网关层进行处理,不用下层到业务逻辑。

  • 统一监控

由于网关是外部服务的入口,所以我们可以在这里监控我们想要的数据,比如入参出参,链路时间。

  • 流量控制,熔断降级

对于流量控制,熔断降级非业务逻辑可以统一放到网关层。

2.GateWay产生的背景
复制代码
Cloud全家桶中有个很重要的组件就是网关,在1.x版本中都是采用的Zuul网关; 但在2.x版本中,zuul的升级一直跳票,SpringCloud最后自己研发了一个网关替代Zuul, 那就是SpringCloud Gateway一句话:gateway是原zuul1.x版的替代 。

SpringCloud Gateway 是 Spring Cloud 的一个全新项目,基于 Spring 5.0+Spring Boot 2.0 和 Project Reactor 等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。 为了提升网关的性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。  zuul是基于Servlet的实现,属于阻塞式编程。而SpringCloudGateway则是基于Spring5中提供的WebFlux,属于响应式编程的实现,具备更好的性能 

二.GateWay配置介绍

1.GateWay三大概念
  • Route(路由):路由是构建网关的基本模块,它由 ID、目标 URI、一系列的断言和过滤器组成,如果断言为 true 则匹配该路由
  • Predicate(断言):参考的是 Java8 中的 java.util.function.Predicate。开发人员可以匹配 HTTP 请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由
  • Filter(过滤):指的是 Spring 框架中 GatewayFilter 的实例,使用过滤器,可以在请求被路由之前或之后对请求进行修改。
yaml 复制代码
spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
      routes:
        - id: service-provider # 路由标示,必须唯一
          uri: lb://SERVICE-PROVIDER # 路由的目标地址;动态路由使用,lb://微服务名
          predicates:  # 路由断言,判断请求是否符合规则
            - Path=/provider/**  # 路径断言,判断路径是否是以/provider开头,如果是则符合
        - id: service-consumer
          uri: lb://SERVICE-CONSUMER
          predicates:
            - Path=/consumer/**
1.1 Route(路由)

gateway 中可以配置多个 Route。一个 Route 由路由 id,转发的 uri,多个 Predicates 以及多个 Filters 构成。处理请求时会按优先级排序,找到第一个满足所有 Predicates 的 Route

1.2 Predicate(断言)

Gateway中predicates配置除了Path断言工厂,还有十几个:

名称 说明 示例
After 是某个时间点后的请求 -- After=2037-01-20T17:42:47.789-07:00[America/Denver]
Before 是某个时间点之前的请求 -- Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai]
Between 是某两个时间点之前的请求 -- Between=2037-01-20T17:42:47.789-07:00[America/Denver], 2037-01-21T17:42:47.789-07:00[America/Denver]
Cookie 请求必须包含某些cookie -- Cookie=chocolate, ch.p
Header 请求必须包含某些header -- Header=X-Request-Id, \d+
Host 请求必须是访问某个host(域名) -- Host=.somehost.org,.anotherhost.org
Method 请求方式必须是指定方式 -- Method=GET,POST
Path 请求路径必须符合指定规则 -- Path=/red/{segment},/blue/**
Query 请求参数必须包含指定参数 -- Query=name, Jack或者- Query=name
RemoteAddr 请求者的ip必须是指定范围 -- RemoteAddr=192.168.1.1/24
Weight 权重处理
1.3 Filter(过滤)

gateway提供了31种不同的内置路由过滤器工厂。常用的如:

名称 说明
AddRequestHeader 给当前请求添加一个请求头
RemoveRequestHeader 移除请求中的一个请求头
AddResponseHeader 给响应结果中添加一个响应头
RemoveResponseHeader 从响应结果中移除有一个响应头
RequestRateLimiter 限制请求的流量

1.2.1 添加过滤器

yaml 复制代码
spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
      routes:
        - id: service-provider # 路由标示,必须唯一
          uri: lb://SERVICE-PROVIDER # 路由的目标地址;动态路由使用,lb://微服务名
          predicates:  # 路由断言,判断请求是否符合规则
            - Path=/provider/**  # 路径断言,判断路径是否是以/provider开头,如果是则符合
        - id: service-consumer
          uri: lb://SERVICE-CONSUMER
          predicates:
            - Path=/consumer/**
          filters: # 针对某个服务添加过滤器
            - AddRequestHeader=name,zhangsan 
      default-filters: # 全局过滤器给请求添加请求头信息
        - AddRequestHeader=name,zhangsan 
        - AddRequestHeader=age,10

1.2.2 自定义全局过滤器(鉴权)

1.2.3 gateway中过滤器的执行顺序

  • 每一个过滤器都必须指定一个int类型的order值,order值越小,优先级越高,执行顺序越靠前
  • GlobalFilter通过实现Ordered接口,或者添加@Order注解来指定order值,由我们自己指定
  • 路由过滤器和defaultFilter的order由gateway指定,默认是按照声明顺序从1递增。
  • 当过滤器的order值一样时,会按照 defaultFilter > 路由过滤器 > GlobalFilter的顺序执行。

三.GateWay工作原理

1.GateWay架构原理

1.拉取注册中心的服务列表

2.获取请求地址,根据routes路由规则判断匹配所拉取的服务列表

3.路由规则匹配上了某个服务列表中的服务,负载均衡转发个对应的服务

2.GateWay的内部流程

1)服务启动时:

1.服务启动时,加载配置文件中的路由配置

2.将路由配置转化为RouteDefinition (封装gateway路由属性信息的bean,即Route的bean定义)

3.RouteLocator读取RouteDefinition并将RouteDefinition 转换成Route对象( Route对象中定义并实例化了路由断言、过滤器、路由地址及路由优先级等信息 ),并提供了获取Route对象的方法

2)客户端请求到达时:

1.Netty Server监听到客户端请求,通过所有路由的路由断言,看是否匹配上路由

2.匹配上路由,封装具体路由的Handler(将路由的一些信息封装到ServerWebExchange对象中),并将对应的过滤器链加入到Handler中

3.拿到具体路由的执行Handler后,执行过滤器链,并通过路由信息转发请求到对应的服务

复制代码
RoutePredicateHandlerMapping的执行顺序

通过路由定位器获取全部路由(RouteLocator)
通过路由的谓语(Predicate)过滤掉不可用的路由信息
查找到路由信息后将路由信息设置当上下文环境中(GATEWAY_ROUTE_ATTR)
返回gatway自定的webhandler(FilteringWebHandler)
相关推荐
阿湯哥3 小时前
Spring AI Alibaba 实现 Workflow 全指南
java·人工智能·spring
萧曵 丶5 小时前
Spring Cloud Alibaba 详解
spring·spring cloud
szm02256 小时前
Spring
java·后端·spring
萧曵 丶7 小时前
Spring 全套高频面试题(由浅到深 完整版)
java·后端·spring
雨中飘荡的记忆9 小时前
Spring Security入门:构建安全应用
spring
老毛肚10 小时前
Spring源码探究2.0
java·后端·spring
涵涵(互关)10 小时前
添加了 @TableId(type = IdType.AUTO) 但仍生成超大 ID
数据库·spring·mybatis
运维@小兵10 小时前
Spring AI入门
java·人工智能·spring
仙俊红11 小时前
Spring 构造器注入 vs 字段注入
java·后端·spring
0和1的舞者11 小时前
Spring 事务核心知识点全梳理(编程式 + 声明式 + 注解详解)
java·后端·spring