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)
相关推荐
Wx-bishekaifayuan1 小时前
django电商易购系统-计算机设计毕业源码61059
java·spring boot·spring·spring cloud·django·sqlite·guava
customer081 小时前
【开源免费】基于SpringBoot+Vue.JS周边产品销售网站(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·java-ee·开源
小白冲鸭2 小时前
【报错解决】使用@SpringJunitConfig时报空指针异常
spring·java后端开发
LuckyLay3 小时前
Spring学习笔记_27——@EnableLoadTimeWeaving
java·spring boot·spring
Stringzhua3 小时前
【SpringCloud】Kafka消息中间件
spring·spring cloud·kafka
成富7 小时前
文本转SQL(Text-to-SQL),场景介绍与 Spring AI 实现
数据库·人工智能·sql·spring·oracle
鹿屿二向箔8 小时前
基于SSM(Spring + Spring MVC + MyBatis)框架的汽车租赁共享平台系统
spring·mvc·mybatis
豪宇刘8 小时前
SpringBoot+Shiro权限管理
java·spring boot·spring
想进大厂的小王8 小时前
项目架构介绍以及Spring cloud、redis、mq 等组件的基本认识
redis·分布式·后端·spring cloud·微服务·架构
customer089 小时前
【开源免费】基于SpringBoot+Vue.JS医院管理系统(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·开源·intellij-idea