gateway之断言的使用详解

gateway产生的背景,为什么要是用gateway

一个系统会被拆分为多个微服务,作为客户端要如何去调用这么多的微服务?如果没有网关的存在,只能在客户端记录每个微服务的地址,然后分别去调用。
例如下图:
请添加图片描述
这样的架构,会存在着诸多的问题:
·每个业务都会需要鉴权、限流、权限校验、跨域等逻辑,如果每个业务都各自为战,自己造轮子实现一遍,完全可以抽出来,放到一个统一的地方去做。
·如果业务量比较简单的话,这种方式前期不会有什么问题,但随着业务越来越复杂,比如淘宝、亚马逊打开一个页面可能会涉及到数百个微服务协同工作,如果每一个微服务都分配一个域名的话,一方面客户端代码会很难维护,涉及到数百个域名,另一方面是连接数的瓶颈,通过抓包发现涉及到了数百个远程调用,这在移动端下会显得非常低效。
后期如果需要对微服务进行重构的话,也会变的非常麻烦,需要客户端配合你一起进行改造,比如商品服务,随着业务变的越来越复杂,后期需要进行拆分成多个微服务,这个时候对外提供
的服务也需要拆分成多个,同时需要客户端配合你进行改造

什么是网关

所谓的API网关,就是指系统的统一入口,它封装了应用程序的内部结构,为客户端提供统一服务,一些与业务本身功能无关的公共逻辑可以在这甲实现,诸如认证、鉴权、监控、路由转发等等
添加上AP网关之后,系统的架构图变成了如下所示:
请添加图片描述

gateway 带来的好处

在这里插入图片描述
网关作为流量的入口,常用的功能包括路由转发,权限校验,限流等。
Spring Cloud Gateway是Spring Cloud官方推出的第二代网关框架,定位于取代Netflix Zuul1.O。相比Zuul来说,Spring Cloud Gateway提供更优秀的性能,更强大的有功能
Spring Cloud Gateway是由WebFlux+Ney+Reactor实现的响应式的API网关。它不能在传统的servlet容器中工作,也不能构建成war包,
Spring Cloud Gateway旨在为微服务架构提供一种简单且有效的API路由的管理方式,并基于Filter方式提供网关的基本功能,例如说安全认证、监控、限流等等

功能特征

1、基于Spring Framework5,Project Reactor和Spring Boot2.0进行构建;
2、动态路由:能够匹配任何请求属性:
3、支持路径重写;
4、集成Spring Cloud服务发现功能(Nacos、Eruka);
5、可集成流控降级功能(Sentinel、.Hystrix);
6、可以对路由指定易于编写的Predicate(断言)和Filter(过滤器);## gateway是如何实现转发

gateway在项目中使用的依赖

父pom中使用的依赖:

<properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <spring-cloud.version>Hoxton.SR12</spring-cloud.version>
        <spring-cloud-alibaba.version>2.2.8.RELEASE</spring-cloud-alibaba.version>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.12.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
<!-- springcloud的版本依赖-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

gateway模块使用的依赖

    <dependencies>
<!--        gateway依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

    </dependencies>

gateway的application.yml配置信息

server:
  port: 8088
spring:
  main:
    web-application-type: reactive
  application:
    name: gateway
# gateway的配置
  cloud:
    gateway:
      #路由规则
      routes: #路由,数组[这里可以放置多个路由]
        #评分管理模块网关路由配置
        - id: shop_router #当前路由标识-要求唯一,默认是UUID;
          uri: http://localhost:8089 #请求最终要被转发的地址;
          order: 1 #路由的优先级——数字越小,代表路由的优先级越高
          predicates: #断言:(条件判断——转发请求要满足的条件)
#            - Path=/shop/** #当请求路径满族path指定的规则时,此路由信息才会正常转发;
#          filters: #过滤器,是在请求传递过程中对请求做一些手脚;
#            - StripPrefix=1 #在请求转发之前去掉一层路径
            - Path=/TestController/**
            - After=2019-12-31T23:59:59.789+08:00[Asia/Shanghai]
            - CheckAuth=gys

什么是断言

Spring Cloud Gateway(简称Gateway)支持断言Predicate功能,该断言功能是基于Spring WebFlux的HandlerMapping实现的。Gateway包含了很多路由断言工厂,并且这些工厂对应着HTTP请求的很多属性进行了处理,当客户端HTTP请求时,HandlerMapping会获取请求参数,并与Gateway中配置的Predicates进行比对,若满足规则就按规则约定进行路由放行,否则拒绝访问或报404错误。

断言分类

官网地址

内置

在配置文件中断言标签下配置的Path,After,都是内置断言,也就是gateway自己给提供的断言
例如:
基于Datatime类型的断言工厂
此类型的断言根据时间做判断,主要有三个:
AfterRoutePredicateFactory:接收一个日期参数,判断请求日期是否晚于指定日期
BeforeRoutePredicateFactory:接收一个日期参数,判断请求日期是否早于指定日期
BetweenRoutePredicateFactory:接收两个日期参数,判断请求日期是否在指定时间段内

自定义

自定义路由断言工厂需要继承AbstractRoutePredicateFactory类,重写apply方法的逻辑。在apply方法中可以通过exchange…getRequest()拿到ServerHttpRequest对象,从而可以获取到情求的参数、清求方式、清求头等信息,

注意点:
1、必须spring组件(必须是bean)
2.类必须加上RoutePredicateFactory作为结尾(约定大于配置)
3.必须继承AbstractRoutePredicateFactory
4.必须声明静态内部类(config)声明属性来接收配置文件中对应的断言的信息

通过shoutcutFieldOrder集合去返回输入内容的信息

5.需要结合shortcutFieldOrderi进行绑定
6,通过apply进行逻辑判断tue就是匹配成功false匹配失败

示例

@Component
public class CheckAuthRoutePredicateFactorya extends AbstractRoutePredicateFactory<CheckAuthRoutePredicateFactorya.Config> {


    public CheckAuthRoutePredicateFactorya() {
        super(Config.class);
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("name");
    }

    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return new GatewayPredicate() {
            @Override
            public boolean test(ServerWebExchange serverWebExchange) {
                if (config.getName().equals("gys")){
                    return true;
                }
                return false;
            }
        };
    }


    /**
 * @description: 用于接收配置文件中断言的信息
 * @author: 
 * @date: 2023/9/19 19:52
 * @param:
 * @return:
 **/
    @Validated
    public static class Config {
        private String name;
        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}

断言和过滤器的不同

1、功能不同:断言用于匹配请求的某些条件,例如请求路径、请求头、请求参数等,它决定了请求是否应该被路由到特定的目标服务。而过滤器用于对请求进行处理和转换,例如添加请求头、修改请求体、记录日志、实现认证授权等。
2、工作原理不同:断言通常用于路由选择的阶段,在接收请求时进行匹配,如果匹配成功,则将请求路由到相应的目标服务。而过滤器则是在请求路由之前或之后应用的,用于对请求进行预处理或后处理,它不会影响路由的选择。
3、使用场景不同:断言通常用于根据请求的某些属性进行路由选择,因此它更贴近网关的底层实现。而过滤器则更加灵活,可用于实现业务逻辑,例如认证授权、请求重试、流量控制等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Gateway自定义断言可以通过实现`GatewayFilterFactory`接口来创建。在实现`GatewayFilterFactory`接口的`apply`方法中,可以使用`ExchangeFilterChain`对象来实现自定义的断言逻辑。以下是一个简单的示例代码: ```java @Component public class CustomPredicateGatewayFilterFactory implements GatewayFilterFactory<CustomPredicateGatewayFilterFactory.Config> { public static final String MY_CUSTOM_HEADER = "my-custom-header"; @Override public GatewayFilter apply(Config config) { return (exchange, chain) -> { HttpHeaders headers = exchange.getRequest().getHeaders(); if (headers.containsKey(MY_CUSTOM_HEADER)) { String value = headers.getFirst(MY_CUSTOM_HEADER); if (config.getValue().equals(value)) { return chain.filter(exchange); } } return exchange.getResponse().setComplete(); }; } @Override public Config newConfig() { return new Config(); } @Override public Class<Config> getConfigClass() { return Config.class; } public static class Config { private String value; public String getValue() { return value; } public void setValue(String value) { this.value = value; } } } ``` 在上面的代码中,我们定义了一个名为`CustomPredicateGatewayFilterFactory`的类,该类实现了`GatewayFilterFactory`接口。我们使用`Config`类来保存配置信息。在`apply`方法中,我们检查请求头中是否包含`my-custom-header`,如果存在,则检查其值是否与`Config`中的值相同。如果相同,则继续执行请求链;否则,返回响应并结束请求。通过这种方式,我们可以实现自定义的断言逻辑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

谷艳爽faye

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值