SpringCloud Gateway

序言

SpringCloud Gateway 作为 Spring Cloud 生态系统中的网关,目标是替代 Zuul,在Spring Cloud 2.0以上版本中,没有对新版本的Zuul 2.0以上最新高性能版本进行集成,仍然还是使用的Zuul 2.0之前的非Reactor模式的老版本。而为了提升网关的性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。

GateWay特点

Spring在2017年下半年迎来了Webflux,Webflux的出现填补了Spring在响应式编程上的空白,Webflux的响应式编程不仅仅是编程风格的改变,而且对于一系列的著名框架,都提供了响应式访问的开发包,比如Netty、Redis等等。

SpringCloud Gateway 使用的Webflux中的reactor-netty响应式编程组件,底层使用了Netty通讯框架。

Springcloud中所集成的Zuul版本,采用的是Tomcat容器,使用的是传统的Servlet IO处理模型

Webflux

 我们知道传统的Web框架,比如说:struts2,springmvc等都是基于Servlet API与Servlet容器基础之上运行的,在Servlet3.1之后才有了异步非阻塞的支持。而WebFlux是一个典型非阻塞异步的框架,它的核心是基于Reactor线程模型的相关API实现的。相对于传统的web框架来说,它可以运行在诸如Netty,Undertow及支持Servlet3.1的容器上,因此它的运行环境的可选择行要比传统web框架多的多。

  根据官方的说法,webflux主要在如下两方面体现出独有的优势:

  • 非阻塞式: 其实在servlet3.1提供了非阻塞的APIWebFlux提供了一种比其更完美的解决方案。使用非阻塞的方式可以利用较小的线程或硬件资源来处理并发进而提高其可伸缩性
  • 函数式编程端点: 老生常谈的编程方式了,Spring5必须让你使用java8,那么函数式编程就是java8重要的特点之一,而WebFlux支持函数式编程来定义路由端点处理请求。

路由转发

SpringCloud Gateway的路由转发有如下的2中方式:但是规则是一样的.所以了解规则了,无论用什么方式都是可以的

  • yml配置文件中设置
  • Bean实例中设置

gateWay的主要功能之一是转发请求,转发规则的定义主要包含三个部分

  1. Route(路由):  路由是网关的基本单元,由ID、URI、一组Predicate、一组Filter组成,根据Predicate进行匹配转发
  2. Predicate(谓语、断言): 路由转发的判断条件,目前SpringCloud Gateway支持多种方式,常见如:Path、Query、Method、Header等,写法必须遵循 key=vlue的形式
  3. Filter(过滤器): 过滤器是路由转发请求时所经过的过滤逻辑,可用于修改请求、响应内容

内置Predicate规则

其实重点还是Predicate,SpringCloud GateWay默认提供了很多路由规则给我们使用(换句话说我们也可以自己自定义路由规则cuiyaonan2000@163.com)

规则举例        说明
Path- Path=/gate/,/rule/当请求的路径为gate、rule开头的时,转发到指定服务器上
Before- Before=2017-01-20T17:42:47.789-07:00[America/Denver]在某个时间之前的请求才会被转发到 指定服务器上
After- After=2017-01-20T17:42:47.789-07:00[America/Denver]在某个时间之后的请求才会被转发
Between- Between=2017-01-20T17:42:47.789-07:00[America/Denver],2017-01-21T17:42:47.789-07:00[America/Denver]在某个时间段之间的才会被转发
Cookie- Cookie=chocolate, ch.p名为chocolate的表单或者满足正则ch.p的表单才会被匹配到进行请求转发
Header- Header=X-Request-Id, \d+携带参数X-Request-Id或者满足\d+的请求头才会匹配
Host- Host=www.hd123.com当主机名为www.hd123.com的时候直接转发到http://localhost:9023服务器上
Method- Method=GET只有GET方法才会匹配转发请求,还可以限定POST、PUT等请求方式
Query Parameter- Query=smile针对请求参数的过滤,可以输入两个参数,第一个是key的名字,第二个是value的过滤.可以只有1个参数.
  • id相当于给规则设置个唯一标识
  • uri表示满足断言后转发的地址,同时也可以是eureka中的服务名称,使用lb:服务名称来进行转发。
  • order表示规则优先级,数字越小优先级越高
  • predicates是判断请求是否满足该规则先决条件

Query Parameter(请求参数)

Query Route Predicate 支持传入两个参数,一个是属性名一个为属性值,属性值可以是正则表达式。(如下所示只要包含smile的请求参数key,注意不是值中包含smile,就符合规则)

server:
  port: 8080
spring:
  application:
  	 name: api-gateway
  cloud:
    gateway:
      routes:
        - id: cuiyaonan2000_id
          uri: https://www.baidu.com
          order: 0
          predicates:
            -Query=smile

如下的表示 key必须为smile,值必须是pu开头的请求才能满足规则

server:
  port: 8080
spring:
  application:
  	 name: api-gateway
  cloud:
    gateway:
      routes:
        - id: cuiyaonan2000_id
          uri: https://www.baidu.com
          order: 0
          predicates:
            -Query=smile,pu.

Header 

一样,也是接收 2 个参数,一个 header 中属性名称和一个正则表达式,这个属性值和正则表达式匹配则执行。(如下所示head头中需要包含X-Request-Id,值必须满足正则表达式)

server:
  port: 8080
spring:
  application:
  	 name: api-gateway
  cloud:
    gateway:
      routes:
        - id: cuiyaonan2000_id
          uri: https://www.baidu.com
          order: 0
          predicates:
            - Header=X-Request-Id, \d+

Cookie 

 可以接收两个参数,一个是 Cookie name ,一个是正则表达式,路由规则会通过获取对应的 Cookie name 值和正则表达式去匹配,如果匹配上就会执行路由,如果没有匹配上则不执行。
server:
  port: 8080
spring:
  application:
  	 name: api-gateway
  cloud:
    gateway:
      routes:
        - id: cuiyaonan2000_id
          uri: https://www.baidu.com
          order: 0
          predicates:
            - Cookie=sessionId, test

Host 

接收一组参数,一组匹配的域名列表,这个模板是一个 ant 分隔的模板,用.号作为分隔符。它通过参数中的主机地址作为匹配规则

server:
  port: 8080
spring:
  application:
  	 name: api-gateway
  cloud:
    gateway:
      routes:
        - id: cuiyaonan2000_id
          uri: https://www.baidu.com
          order: 0
          predicates:
            - Host=**.baidu.com

Method

只有1个参数???或者多个参数???

server:
  port: 8080
spring:
  application:
  	 name: api-gateway
  cloud:
    gateway:
      routes:
        - id: cuiyaonan2000_id
          uri: https://www.baidu.com
          order: 0
          predicates:
            - Method=GET

Path

1个参数,是否可以用逗号分隔成多个地址进行匹配?????

server:
  port: 8080
spring:
  application:
  	 name: api-gateway
  cloud:
    gateway:
      routes:
        - id: cuiyaonan2000_id
          uri: https://www.baidu.com
          order: 0
          predicates:
            -Path=/cuiyaonan2000/{segment}

Ip

Predicate 也支持通过设置某个 ip 区间号段的请求才会路由,RemoteAddr Route Predicate 接受 cidr 符号(IPv4 或 IPv6 )字符串的列表(最小大小为1),例如 192.168.0.1/16 (其中 192.168.0.1 是 IP 地址,16 是子网掩码)

server:
  port: 8080
spring:
  application:
  	 name: api-gateway
  cloud:
    gateway:
      routes:
        - id: cuiyaonan2000_id
          uri: https://www.baidu.com
          order: 0
          predicates:
            - RemoteAddr=192.168.1.1/24

组合使用

各种 Predicates 同时存在于同一个路由时,请求必须同时满足所有的条件才被这个路由匹配

一个请求满足多个路由的断言条件时,请求只会被首个成功匹配的路由ID转发

server:
  port: 8080
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        - id: cuiyaonan2000_id
          uri: https://www.baidu.com
          order: 0
          predicates:
            - Host=**.cuiyaonan2000.org
            - Path=/headers
            - Method=GET
            - Header=X-Request-Id, \d+
            - Query=foo, ba.
            - Query=baz
            - Cookie=chocolate, ch.p

Filter

Spring-Cloud-Gateway基于过滤器实现,同zuul类似,有prepost两种方式的filter,分别处理前置逻辑后置逻辑。客户端的请求先经过pre类型的filter,然后将请求转发到具体的业务服务,收到业务服务的响应之后,再经过post类型的filter处理,最后返回响应到客户端。

过滤器执行流程如下,order越大优先级越低.所有的过滤器都会顺序执行.

规则举例说明
PrefixPath- PrefixPath=/app在请求路径前加上app
RewritePath- RewritePath=/test, /app/test访问localhost:9022/test,请求会转发到localhost:8001/app/test
SetPath- SetPath=/app/{path}通过模板设置路径,转发的规则时会在路径前增加app,{path}表示原请求路径
RedirectTo重定向
RemoveRequestHeader去掉某个请求头信息

PrefixPath

对所有的请求路径添加前缀:

spring:
  cloud:
    gateway:
      routes:
      - id: prefixpath_route
        uri: https://example.org
        filters:
        - PrefixPath=/mypath

RedirectTo

spring:
  cloud:
    gateway:
      routes:
      - id: prefixpath_route
        uri: https://example.org
        filters:
        - RedirectTo=302, https://acme.org

RemoveRequestHeader

去掉某个请求头信息:

spring:
  cloud:
    gateway:
      routes:
      - id: removerequestheader_route
        uri: https://example.org
        filters:
        - RemoveRequestHeader=X-Request-Foo

RemoveResponseHeader

去掉某个回执头信息:

spring:
  cloud:
    gateway:
      routes:
      - id: removerequestheader_route
        uri: https://example.org
        filters:
        - RemoveResponseHeader=X-Request-Foo

RemoveRequestParameter

去掉某个请求参数信息:

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

RewritePath

改写路径:/where/... 改成 test/...

spring:
  cloud:
    gateway:
      routes:
      - id: rewrite_filter
        uri: http://localhost:8081
        predicates:
        - Path=/test/**
        filters:
        - RewritePath=/where(?<segment>/?.*), /test(?<segment>/?.*)

SetPath

设置请求路径,与RewritePath类似。

如/red/blue的请求被转发到/blue。

spring:
  cloud:
    gateway:
      routes:
      - id: setpath_route
        uri: https://example.org
        predicates:
        - Path=/red/{segment}
        filters:
        - SetPath=/{segment}

SetRequestHeader

设置请求头信息。

spring:
  cloud:
    gateway:
      routes:
      - id: setrequestheader_route
        uri: https://example.org
        filters:
        - SetRequestHeader=X-Request-Red, Blue

SetStatus

设置回执状态码。

spring:
  cloud:
    gateway:
      routes:
      - id: setstatusint_route
        uri: https://example.org
        filters:
        - SetStatus=401

StripPrefix

跳过指定路径: 请求/name/blue/red会转发到/red。

spring:
  cloud:
    gateway:
      routes:
      - id: nameRoot
        uri: https://nameservice
        predicates:
        - Path=/name/**
        filters:
        - StripPrefix=2

RequestSize

请求大小。

超过5M的请求会返回413错误。

spring:
  cloud:
    gateway:
      routes:
      - id: request_size_route
        uri: http://localhost:8080/upload
        predicates:
        - Path=/upload
        filters:
        - name: RequestSize
          args:
            maxSize: 5000000

Default-filters

对所有请求添加过滤器。

spring:
  cloud:
    gateway:
      default-filters:
      - AddResponseHeader=X-Response-Default-Red, Default-Blue
      - PrefixPath=/httpbin

GateWay 的熔断

此熔断与微服务Feign的熔断是一个意思,但是应用场景不一样.

  • 微服务的熔断:  针对的是微服务之间的相互调用的熔断处理
  • GateWay的熔断: 针对的是C端(即外部调用的)的的调用熔断.

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cuiyaonan2000

给包烟抽吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值