• SpringCloud 组件Gateway服务网关【断言工厂&过滤器工厂】


    目录

    1:断言工厂

    2:过滤器工厂

    2.1:路由过滤器的种类

    2.2:请求头过滤器

    2.3:默认过滤器

    2.4:总结


    1:断言工厂

    路由断言工厂Route Predicate Factory

    路由配置包括:

    1. 路由id:路由的唯一标示

    2. 路由目标(uri):路由的目标地址,http代表固定地址,lb代表根据服务名负载均衡

    3. 路由断言(predicates):路由断言,判断请求是否符合要求,符合则转发到路由目的地

    4. 路由过滤器(filters):路由过滤器,请求或响应做处理

    示例:

    我们在配置文件中写的断言规则只是字符串,这些字符串会被Predicate Factory读取并处理,转变为路由判断的条件

    例如Path=/consumer/**是按照路径匹配的一种规则,这个规则是由

    org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory类来

    处理的,像这样的断言工厂在SpringCloudGateway还有十几个:

    名称说明示例
    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权重处理

    在官方网站的示例中可以找到Spring Cloud Gateway 

    像示例中的Path,用到的是官网中5.8的路由断言工厂的规则

    演示一下5.1中的断言工厂中的After规则

    示例1:在2031年之后可访问,那当前时间肯定是不符合时间规则,所以无法通过判断进行了路由跳转,找不到报错404

    1. predicates: #断言,也就是判断请求是否复合路由规则的条件
    2. - Path=/consumer/** #这个是按照路径匹配,只要以/consumer/开头就符合要求
    3. - After=2031-01-20T17:42:47.789-07:00[Asia/Shanghai]

     

    演示一下5.2中的断言工厂中的Before规则

    示例2:在2031年之前可访问,那当前时间是符合时间规则,即可通过路由的跳转

     示例3:通过请求参数匹配

    1. spring:
    2. cloud:
    3. gateway:
    4. routes:
    5. - id: query
    6. uri: http://www.czxy.com
    7. predicates:
    8. - Query=my,123
    9. #访问路径,有参数my将转发到www.czxy.com
    10. http://localhost:10010/?my=123

    PredicateFactory的作用是什么呢?

    断言工厂,读取配置中使用的是哪种断言工厂的规则,而后解析成对应的条件,将来请求进来了进行判断!

    Path=/user/**是什么含义呢?

     判断请求路径是否为user开头的规则条件,只要符合user开头就是符合了条件!

    注意:

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

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

    2:过滤器工厂

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

     

     

    • 路由过滤器允许以某种方式修改传入的HTTP请求或传出HTTP响应。对请求或者响应进行增强

    2.1:路由过滤器的种类

    链接:spring

    Spring提供了31种不同的路由过滤器工厂,可到官网查看。例如:

     

    过滤规则实例说明
    PrefixPath- PrefixPath=/app对所有的请求路径添加前缀app
    RedirectTo- RedirectTo=302, 首页 - 传智专修学院重定向,配置包含重定向的返回码和地址
    RemoveRequestHeader- RemoveRequestHeader=X-Request-Foo去掉某个请求头信息
    RemoveResponseHeade- RemoveResponseHeader=X-Request-Foo去掉某个响应头信息
    RemoveRequestParameter- RemoveRequestParameter=red去掉某个请求参数信息
    RewritePath- RewritePath=/where(?/?.), /test(?/?.)改写路径 /where/... 改成 /test/...
    SetPath- SetPath=/{segment}设置请求路径,与RewritePath类似
    SetRequestHeader- SetRequestHeader=X-Request-Red, Blue设置请求头信息
    SetStatus- SetStatus=401设置响应状态码
    StripPrefix- StripPrefix=2跳过指定路径
    RequestSize- name: RequestSize args: maxSize: 5000000请求大小

    实例1:跳过指定路径(yml文件配置方法)

    1. spring:
    2. cloud:
    3. gateway:
    4. routes:
    5. - id: consumer
    6. uri: lb://service-consumer
    7. predicates:
    8. - Path=/consumer/**
    9. filters:
    10. - StripPrefix=1

     实例2:添加前缀(yml文件配置方法)

    1. #rest --> http://localhost:10010/consumer/echo/123
    2. #fegin --> http://localhost:10010/consumer/feign/echo/123
    3. spring:
    4. cloud:
    5. gateway:
    6. routes:
    7. - id: PrefixPath
    8. uri: lb://service-consumer
    9. predicates:
    10. - Path=/consumer/**
    11. filters:
    12. - StripPrefix=1
    13. - PrefixPath=/feign
    14. #feign --> http://localhost:10010/consumer/echo/123

    实例3:改写路径(yml文件配置方法)

    1. #rest --> http://localhost:10010/consumer/echo/123
    2. spring:
    3. cloud:
    4. gateway:
    5. routes:
    6. - id: RewritePath
    7. uri: lb://service-consumer
    8. predicates:
    9. - Path=/consumer/**
    10. filters:
    11. - RewritePath=/consumer(?/?.*), $\{segment}
    12. # 正则表达式详解:
    13. # ? --> 名称为 segment 的组
    14. # /? --> /出现0次或1次
    15. # .* --> 任意字符出现0次或多次
    16. # 总结:将 /?.*匹配到的结果捕获到名称为segment的组中
    17. # $\{segment} --> 将名称为 segment 的分组捕获到的文本置换到此处
    18. ## 注意,\的出现是由于避免 yaml 语法认为这是一个变量

    2.2:请求头过滤器(示例官网过滤器工厂6.1程序演示)

    下面我们以AddRequestHeader 为例。

    需求:给所有进入service-consumer的请求添加一个请求头:Truth=I can succeed

    只需要修改gateway服务的application.yml文件,添加路由过滤即可:

    1. #端口号
    2. server:
    3. port: 10010
    4. spring:
    5. application:
    6. name: test-gateway
    7. cloud:
    8. nacos:
    9. discovery:
    10. server-addr: localhost:8848 #nacos服务地址
    11. gateway:
    12. routes: # 网关路由配置
    13. - id: consumer #自定义,路由id,只要唯一即可
    14. uri: lb://service-consumer #访问路径,路由的目标地址 lb是负载均衡,后面跟着服务名称
    15. predicates: #断言,也就是判断请求是否复合路由规则的条件
    16. - Path=/consumer/** #这个是按照路径匹配,只要以/consumer/开头就符合要求
    17. - Before=2031-01-20T17:42:47.789-07:00[Asia/Shanghai]
    18. filters: #过滤器
    19. - AddRequestHeader=qx,I can succeed ! #添加请求头
    20. - StripPrefix=1 #跳过前缀进行访问,这里即使把请求参数中consumer跳过,发送请求

     编写controller测试方法用来测试请求头中是否携带

    1. @RestController
    2. @RequestMapping("/user")
    3. public class UserController {
    4. /**
    5. * 测试过滤器工程,添加请求头
    6. * @param
    7. * @return
    8. */
    9. @GetMapping("/test")
    10. public String test(@RequestHeader("qx") String qx){
    11. return qx;
    12. }

     

    当前过滤器写在service-consumer服务路由下,因此仅仅对访问service-consumer的请求有效。

    2.3:默认过滤器

    如果要对所有的路由都生效,则可以将过滤器工厂写到default下。格式如下:

    1. #端口号
    2. server:
    3. port: 10010
    4. spring:
    5. application:
    6. name: test-gateway
    7. cloud:
    8. nacos:
    9. discovery:
    10. server-addr: localhost:8848 #nacos服务地址
    11. gateway:
    12. routes: # 网关路由配置
    13. - id: consumer #自定义,路由id,只要唯一即可
    14. uri: lb://service-consumer #访问路径,路由的目标地址 lb是负载均衡,后面跟着服务名称
    15. predicates: #断言,也就是判断请求是否复合路由规则的条件
    16. - Path=/consumer/** #这个是按照路径匹配,只要以/consumer/开头就符合要求
    17. - Before=2031-01-20T17:42:47.789-07:00[Asia/Shanghai]
    18. default-filters: # 默认过滤项
    19. - AddRequestHeader=qx,I can succeed ! #添加请求头

    2.4:总结

    过滤器的作用是什么?

    ① 对路由的请求或响应做加工处理,比如添加请求头

    ② 配置在路由下的过滤器只对当前路由的请求生效

    defaultFilters的作用是什么?

    ① 对所有路由都生效的过滤器

  • 相关阅读:
    Nmap渗透测试指南之探索网络
    分享一个使用get_hash_value比对数据脚本
    【Vue】基础系列(二二)Vue基础--Vue模板语法-vue数据绑定原理-插值语法-指令语法-元素的显示隐藏
    new`是如何创建对象实例的?
    pytest接口自动化测试框架 | 为什么要做pytest插件的二次开发
    八股文死记硬背打脸记
    【C#】RestSharp踩坑日记
    eProsima Fast DDS(1)
    JVM内存模型:理解Java程序的内存管理
    39.JS插件
  • 原文地址:https://blog.csdn.net/m0_64550837/article/details/128040472