一、概述

  Spring Cloud Gateway将路由作为Spring WebFlux HandlerMapping基础结构的一部分进行匹配。 Spring Cloud Gateway包含许多内置的Route Predicate Factories。所有这些谓词都匹配HTTP请求的不同属性。多路线谓词工厂可以组合,并通过逻辑and。

  路由选择是通过Predicate函数式接口进行判断当前路由是否满足给定条件。

  附注:关于jdk8的Predicate
  Predicate<T> 接受一个输入参数,返回一个布尔值结果。该接口包含多种默认方法来将Predicate组合成其他复杂的逻辑(比如:与,或,非)。可以用于接口请求参数校验、判断新老数据是否有变化需要进行更新操作。
add--与、or--或、negate--非
  boolean test(T t); 判断
  Predicate<T> and(Predicate<? super T> other) 接收一个Predicate类型,也就是将传入的条件和当前条件以并且(AND)的关系组合
  Predicate<T> or(Predicate<? super T> other)接收一个Predicate类型,也就是将传入的条件和当前条件以或(OR)的关系组合
  更多参看:https://www.cnblogs.com/bjlhx/p/9711292.html

1.1、路由谓词创建及使用

1️⃣、加载路由中的Predicate

  在路由定位器中以及看到了通过路由定义转换路由方法,其中包含了通过谓语定义(PredicateDefinition)转换谓语(Predicate)的部分,在RouteDefinitionRouteLocator类中源码如下:

/**
* 返回组合的谓词
* @param routeDefinition
* @return
*/
private Predicate<ServerWebExchange> combinePredicates(RouteDefinition routeDefinition) {
//获取RouteDefinition中的PredicateDefinition集合
List<PredicateDefinition> predicates = routeDefinition.getPredicates(); Predicate<ServerWebExchange> predicate = lookup(routeDefinition, predicates.get(0)); for (PredicateDefinition andPredicate : predicates.subList(1, predicates.size())) {
Predicate<ServerWebExchange> found = lookup(routeDefinition, andPredicate);
//返回一个组合的谓词,表示该谓词与另一个谓词的短路逻辑AND
predicate = predicate.and(found);
} return predicate;
} /**
* 获取一个谓语定义(PredicateDefinition)转换的谓语
* @param route
* @param predicate
* @return
*/
@SuppressWarnings("unchecked")
private Predicate<ServerWebExchange> lookup(RouteDefinition route, PredicateDefinition predicate) {
//获取谓语创建工厂
RoutePredicateFactory<Object> factory = this.predicates.get(predicate.getName());
if (factory == null) {
throw new IllegalArgumentException("Unable to find RoutePredicateFactory with name " + predicate.getName());
}
//获取参数
Map<String, String> args = predicate.getArgs();
if (logger.isDebugEnabled()) {
logger.debug("RouteDefinition " + route.getId() + " applying "
+ args + " to " + predicate.getName());
} //组装参数
Map<String, Object> properties = factory.shortcutType().normalize(args, factory, this.parser, this.beanFactory);
//构建创建谓语的配置信息
Object config = factory.newConfig();
ConfigurationUtils.bind(config, properties,
factory.shortcutFieldPrefix(), predicate.getName(), validator);
if (this.publisher != null) {
this.publisher.publishEvent(new PredicateArgsEvent(this, route.getId(), properties));
}
//通过谓语工厂构建谓语
return factory.apply(config);
}
  • 获取路由定义(routeDefinition)所有的谓语定位(PredicateDefinition)
  • 以此根据谓语定义(PredicateDefinition)查找谓语对于的创建工厂(RoutePredicateFactory) 创建谓语
  • 通过 Predicate<T>接口 and方法合并谓语集合返回一个新的复合谓语

2️⃣、使用路由Predicate判断路由是否可用

  在Spring-Cloud-Gateway之请求处理流程里,在handlerMapping中通过路由定位器获取所有路由,并过滤掉谓语判断失败的路由,最终获取满足条件的路由

protected Mono<Route> lookupRoute(ServerWebExchange exchange) {
//通过路由定位器获取路由信息
return this.routeLocator.getRoutes()
.filter(route -> {
exchange.getAttributes().put(GATEWAY_PREDICATE_ROUTE_ATTR, route.getId());
//返回通过谓语过滤的路由信息
return route.getPredicate().test(exchange);
});
}

  通过上面两步可以看到了整个路由的条件创建以及使用的地方以及流程,Spring-Cloud-Gateway通过Predicate接口完成简单条件组合以及判断。

1.2、RoutePredicateFactory 路由谓词工厂

  Spring-Cloud-Gateway通过RoutePredicateFactory创建Predicate。其中预制了很多RoutePredicateFactory使其可以通过简单的配置就可以创建出理想的Predicate。
查看类Uml图
  

按照子类功能划分:

  

1️⃣、MethodRoutePredicateFactory

/**
* 请求方式(GET,POST,DEL,PUT)校验匹配创建工厂
*/
public class MethodRoutePredicateFactory extends AbstractRoutePredicateFactory<MethodRoutePredicateFactory.Config> { public static final String METHOD_KEY = "method";
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return exchange -> {
//获取当前请求的HttpMethod
HttpMethod requestMethod = exchange.getRequest().getMethod();
//校验请求HttpMethod与配置是否一致
return requestMethod == config.getMethod();
};
} public static class Config {
/**
* http 请求Method
*/
private HttpMethod method; public HttpMethod getMethod() {
return method;
} public void setMethod(HttpMethod method) {
this.method = method;
}
}
}

配置示例

spring:
cloud:
gateway:
routes:
# =====================================
- id: method_route
uri: http://example.org
predicates:
- Method=GET

过程:

  • Method=GET 会被解析成PredicateDefinition对象 (name =Method ,args= GET)
  • 通过PredicateDefinition的Name找到MethodRoutePredicateFactory工厂
  • 通过 PredicateDefinition 的args 创建Config对象(HttpMethod=GET)
  • 通过 MethodRoutePredicateFactory工厂的apply方法传入config创建Predicate对象。

1.3、全部谓词配置

1.3.1、After Route Predicate Factory

  此谓词匹配当前日期时间之后发生的请求。

  application.yml

spring:
cloud:
gateway:
routes:
- id: after_route
uri: http://example.org
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]

1.3.2、Before Route Predicate Factory

  此谓词匹配在当前日期时间之前发生的请求。

  application.yml

spring:
cloud:
gateway:
routes:
- id: before_route
uri: http://example.org
predicates:
- Before=2017-01-20T17:42:47.789-07:00[America/Denver]

1.3.3、Between Route Predicate Factory

  此谓词匹配datetime1之后和datetime2之前发生的请求。 datetime2参数必须在datetime1之后。

  application.yml

spring:
cloud:
gateway:
routes:
- id: between_route
uri: http://example.org
predicates:
- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]

1.3.4、Cookie Route Predicate Factory

  Cookie Route Predicate Factory有两个参数,cookie名称和正则表达式。此谓词匹配具有给定名称且值与正则表达式匹配的cookie。

  application.yml

spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: http://example.org
predicates:
- Cookie=chocolate, ch.p

  此路由匹配请求有一个名为chocolate的cookie,其值与ch.p正则表达式匹配。

1.3.5、Header Route Predicate Factory

  Header Route Predicate Factory有两个参数,标题名称和正则表达式。此谓词与具有给定名称且值与正则表达式匹配的标头匹配。

  application.yml

spring:
cloud:
gateway:
routes:
- id: header_route
uri: http://example.org
predicates:
- Header=X-Request-Id, \d+

  如果请求具有名为X-Request-Id的标头,则该路由匹配,其值与\ d +正则表达式匹配(具有一个或多个数字的值)。

1.3.6、Host Route Predicate Factory

  Host Route Predicate Factory采用一个参数:主机名模式。该模式是一种Ant样式模式“.”作为分隔符。此谓词匹配与模式匹配的Host标头。

  application.yml

spring:
cloud:
gateway:
routes:
- id: host_route
uri: http://example.org
predicates:
- Host=**.somehost.org

  如果请求的主机头具有值www.somehost.org或beta.somehost.org,则此路由将匹配。

1.3.7、Method Route Predicate Factory

  Method Route Predicate Factory采用一个参数:要匹配的HTTP方法。

spring:
cloud:
gateway:
routes:
- id: method_route
uri: http://example.org
predicates:
- Method=GET

1.3.8、Path Route Predicate Factory

spring:
cloud:
gateway:
routes:
- id: host_route
uri: http://example.org
predicates:
- Path=/foo/{segment}

/foo/1 or /foo/bar.

1.3.9、Query Route Predicate Factory

Query Route Predicate Factory有两个参数:一个必需的参数和一个可选的正则表达式。

spring:
cloud:
gateway:
routes:
- id: query_route
uri: http://example.org
predicates:
- Query=baz

如果请求包含baz查询参数,则此路由将匹配。

spring:
cloud:
gateway:
routes:
- id: query_route
uri: http://example.org
predicates:
- Query=foo, ba.

如果请求包含其值与ba匹配的foo查询参数,则此路由将匹配。 regexp,所以bar和baz匹配。

1.3.10、RemoteAddr Route Predicate Factory

RemoteAddr Route Predicate Factory采用CIDR符号(IPv4或IPv6)字符串的列表(最小值为1),例如, 192.168.0.1/16(其中192.168.0.1是IP地址,16是子网掩码)。

spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: http://example.org
predicates:
- RemoteAddr=192.168.1.1/24

如果请求的远程地址是例如192.168.1.10,则此路由将匹配。

008-spring cloud gateway-路由谓词RoutePredicate、RoutePredicateFactory的更多相关文章

  1. SpringCloud无废话入门05:Spring Cloud Gateway路由、filter、熔断

    1.什么是路由网关 截至目前为止的例子中,我们创建了一个service,叫做:HelloService,然后我们把它部署到了两台服务器(即提供了两个provider),然后我们又使用ribbon将其做 ...

  2. Spring Cloud Gateway - 路由法则

    1. After Route Predicate Factory 输入一个参数:时间,匹配该时间之后的请求,示例配置: spring: cloud: gateway: routes: - id: af ...

  3. Spring Cloud Alibaba学习笔记(16) - Spring Cloud Gateway 内置的路由谓词工厂

    Spring Cloud Gateway路由配置的两种形式 Spring Cloud Gateway的路由配置有两种形式,分别是路由到指定的URL以及路由到指定的微服务,在上文博客的示例中我们就已经使 ...

  4. spring cloud gateway 深入了解 - Predicate

    文章来源 spring cloud gateway 通过谓词(Predicate)来匹配来自用户的请求 为了方便,使用postman测试不同的谓词的效果 路径谓词(Predicate)—— 最简单的谓 ...

  5. 看完就会的Spring Cloud Gateway

    在前面几节,我给大家介绍了当一个系统拆分成微服务后,会产生的问题与解决方案:服务如何发现与管理(Nacos注册中心实战),服务与服务如何通信(Ribbon, Feign实战) 今天我们就来聊一聊另一个 ...

  6. Spring Cloud Gateway 没有链路信息,我 TM 人傻了(上)

    本系列是 我TM人傻了 系列第五期[捂脸],往期精彩回顾: 升级到Spring 5.3.x之后,GC次数急剧增加,我TM人傻了 这个大表走索引字段查询的 SQL 怎么就成全扫描了,我TM人傻了 获取异 ...

  7. Spring Cloud Gateway 没有链路信息,我 TM 人傻了(中)

    本系列是 我TM人傻了 系列第五期[捂脸],往期精彩回顾: 升级到Spring 5.3.x之后,GC次数急剧增加,我TM人傻了 这个大表走索引字段查询的 SQL 怎么就成全扫描了,我TM人傻了 获取异 ...

  8. Spring Cloud Gateway夺命连环10问?

    大家好,我是不才陈某~ 最近有很多小伙伴私信我催更 <Spring Cloud 进阶>,陈某也总结了一下,最终原因就是陈某之前力求一篇文章将一个组件重要知识点讲透,这样导致了文章篇幅很长, ...

  9. Spring Cloud Gateway(六):路由谓词工厂 RoutePredicateFactory

    本文基于 spring cloud gateway 2.0.1 1.简介 Spring Cloud Gateway 创建 Route 对象时, 使用 RoutePredicateFactory 创建 ...

  10. Spring Cloud Alibaba学习笔记(17) - Spring Cloud Gateway 自定义路由谓词工厂

    在前文中,我们介绍了Spring Cloud Gateway内置了一系列的路由谓词工厂,但是如果这些内置的路由谓词工厂不能满足业务需求的话,我们可以自定义路由谓词工厂来实现特定的需求. 例如有某个服务 ...

随机推荐

  1. 利用pdb获取未导出符号

      BOOL InitSymHandler(HANDLE hProc)   {   CHAR SymPath[MAX_PATH], CurDir[MAX_PATH];       GetCurrent ...

  2. 异构GoldenGate 12c 单向复制配置

    1.分别在windows2008.linux平台部署oracle 11.2.0.4 2.分别在windows2008.linux平台部署gg. 2.1 windows平台: gg的安装目录位 C:\o ...

  3. 提交代码到自己的github仓库

    说起来尴尬,好几年前就搞了github建了仓库,当时玩得还有点6,后来一直的公司都是svn,自己业务项目也没玩,都忘了要怎么提交代码到自己的仓库了. 这边再来一波记录吧. 一.配置用户名 git co ...

  4. CentOS 安装apache

    yum 安装apache yum –y install httpd 设置开机启动 chkconfig --levels 235 httpd on 启动 /etc/init.d/httpd start ...

  5. 游戏AI-行为树

    参考: 游戏AI—行为树研究及实现 GAD腾讯游戏开发者平台:游戏中的人工智能AI 腾讯开源项目behaviac 占坑,待编辑

  6. Jquery操作select选项集合,判断集合中是否存在option

    转载:http://www.cnblogs.com/pepcod/archive/2012/07/03/JavaScript.html Query获取Select选择的Text和Value: 语法解释 ...

  7. 惠普hp服务器通过iLO接口远程安装操作系统

    我们以hp proliant sl210t的机器为例,我们在配置好iLO接口的远程管理后,我们便可以通过iLO进行操作系统的安装 关于惠普服务器的iLO配置,可参笔者的另一篇文章<关于hp pr ...

  8. 【BZOJ5090】组题 分数规划

    [BZOJ5090]组题 Description 著名出题人小Q的备忘录上共有n道可以出的题目,按照顺序依次编号为1到n,其中第i道题目的难度系数被小Q估计为a_i,难度系数越高,题目越难,负数表示这 ...

  9. [工具] f.lux – 随时间改变屏幕色温护眼

    f.lux 是一款根据时间变化来改变屏幕色温的软件.让你在深夜也能感受到太阳的温暖,顺便还有助于睡眠. 在 f.lux 里,首先设置一个适合你的变化色温范围,白天的色温控制在 6500K 以下,晚上的 ...

  10. 爬取博主的所有文章并保存为PDF文件

    继续改进上一个项目,上次我们爬取了所有文章,但是保存为TXT文件,查看不方便,而且还无法保存文章中的代码和图片. 所以这次保存为PDF文件,方便查看. 需要的工具: 1.wkhtmltopdf安装包, ...