0


SpringColoud GateWay 核心组件

优质博文:IT-BLOG-CN

**【1】

Route

路由:**

Gateway

的基本构建模块,它由

ID

、目标

URL

、断言集合和过滤器集合组成。如果聚合断言结果为真,则匹配到该路由。

**

Route

路由-动态路由实现原理:**配置变化

Apollo
  • 服务地址实例变化
    Nacos
    
    Spring Cloud Gateway
    
    通过
    RouteDefinitionLocator
    
    RouteRefreshListener
    
    等组件实现动态路由。

先看下配置信息,方便后面原理的理解:

SpringCloudGateway bootstrap.yml

的配置如下:

spring:application:name: gateway-service
  cloud:nacos:discovery:server-addr: ${NACOS_SERVER_ADDR:localhost:8848}apollo:bootstrap:enabled:truemeta: ${APOLLO_META:localhost:8080}
application.yml

的配置如下:

spring:cloud:gateway:discovery:locator:enabled:truelower-case-service-id:trueapollo:bootstrap:namespaces: application # 1、登录 Apollo 控制台。 2、创建一个新的配置,例如 application.yml。 3、内容就是上看配置的SpringCloud Gateway 配置的路由信息

1、

RouteDefinitionLocator

Spring Cloud Gateway

启动时,会通过

RouteDefinitionLocator

Apollo

加载初始的路由定义。
2、

DiscoveryClientRouteDefinitionLocator

:使用

Nacos

进行服务发现,从

Nacos

获取动态路由定义。
3、

RouteDefinitionRepository

:加载的路由定义会存储在

RouteDefinitionRepository

中,供后续路由匹配使用。
4、

RouteRefreshListener

:监听路由定义的变化事件(如配置更新、服务实例变化等)。当监听到路由定义变化事件时,触发路由刷新操作,更新网关的路由规则,重新加载并应用新的路由配置。

GatewayHandlerMapping

根据预先配置的路由信息和请求的属性(如路径、方法、头部信息等)来确定哪个路由与请求匹配。它使用谓词

Predicates

来进行匹配判断。

**【2】

Predicate

断言:** 这是一个

Java 8 Function Predicate

。输入类型是

Spring Framework ServerWebExchange

。允许开发人员匹配来自

HTTP

请求的任何内容,例如

Header

或参数。

Predicate

接受一个输入参数,返回一个布尔值结果。

Spring Cloud Gateway

内置了许多

Predict

,这些

Predict

的源码在

org.springframework.cloud.gateway.handler.predicate

包中,如果读者有兴趣可以阅读一下。现在列举各种 Predicate如下图:

在上图中,有很多类型的

Predicate

,比如说时间类型的

Predicated

[

AfterRoutePredicateFactory BeforeRoutePredicateFactory BetweenRoutePredicateFactory

],当只有满足特定时间要求的请求会进入到此

Predicate

中,并交由

Router

处理;

Cookie

类型的

CookieRoutePredicateFactory

,指定的

Cookie

满足正则匹配,才会进入此

Router

。以及

host

method

path

querparam

remoteaddr

类型的

Predicate

,每一种

Predicate

都会对当前的客户端请求进行判断,是否满足当前的要求,如果满足则交给当前请求处理。如果有很多个

Predicate

,并且一个请求满足多个

Predicate

,则按照配置的顺序第一个生效。

Predicate 断言配置:

server:port:8080spring:application:name: api-gateway
  cloud:gateway:routes:-id: gateway-service
          uri: https://www.baidu.com
          order:0predicates:- After=2017-01-20T17:42:47.789-07:00[America/Denver]- Host=**.foo.org- Path=/headers
            - Method=GET
            - Header=X-Request-Id, \d+
            - Query=foo, ba.
            - Query=baz
            - Cookie=chocolate, ch.p

在上面的配置文件中,配置了服务的端口为

8080

,配置

spring cloud gateway

相关的配置,**

id

标签配置的是

router

id

**,每个

router

都需要一个唯一的

id

,**

uri

配置的是将请求路由到哪里**,本案例全部路由到

https://www.baidu.com

**

Predicates

:**

After=2017-01-20T17:42:47.789-07:00[America/Denver]

会被解析成

PredicateDefinition

对象

name =After ,args= 2017-01-20T17:42:47.789-07:00[America/Denver]

。需要注意的是

Predicates

After

这个配置,遵循契约大于配置的思想,它实际被

AfterRoutePredicateFactory

这个类所处理,这个

After

就是指定了它的

Gateway web handler

类为

AfterRoutePredicateFactory

,同理,其他类型的

Predicate

也遵循这个规则。当请求的时间在这个配置的时间之后,请求会被路由到指定的

URL

。跟时间相关的

Predicates

还有

Before Route Predicate Factory

Between Route Predicate Factory

,读者可以自行查阅官方文档,再次不再演示。

**

Query=baz

:**

Query

的值以键值对的方式进行配置,这样在请求过来时会对属性值和正则进行匹配,匹配上才会走路由。经过测试发现只要请求汇总带有

baz

参数即会匹配路由[

localhost:8080?baz=x&id=2

],不带

baz

参数则不会匹配。

Query=foo, ba.

:这样只要当请求中包含

foo

属性并且参数值是以

ba

开头的长度为三位的字符串才会进行匹配和路由。使用

curl

测试,命令行输入:

curl localhost:8080?foo=bab

测试可以返回页面代码,将

foo

的属性值改为

babx

再次访问就会报

404

,证明路由需要匹配正则表达式才会进行路由。

Header=X-Request-Id

,

\d+

:使用

curl

测试,命令行输入:

curl http://localhost:8080 -H "X-Request-Id:88"

则返回页面代码证明匹配成功。将参数

-H "X-Request-Id:88"改为-H "X-Request-Id:spring"

再次执行时返回

404

证明没有匹配。

【3】

Filter

过滤器:方案一:写死在代码中

@BeanpublicRouteLocatorcustomRouteLocator(RouteLocatorBuilder builder){return builder.routes()//openapi路由转发.route("openapi_route", p -> p.path("/openapi/**").filters(f->f.removeRequestHeader("Expect")).uri("lb://order-openapi-service")).build();}

方案二:配置文件

yml
# gateway 的配置形式routes:-id: order-service #路由ID,没有规定规则但要求唯一,建议配合服务名。uri: lb://order-service
    predicates:- Path=/order/**filters:- ValidateCodeGatewayFilter

**

Filter

过滤器:

Filter

按处理顺序

Pre Filter / Post Filter

**

**

Filter

按作用范围分为:**

GlobalFilter

全局过滤器。

GatewayFilter

指定路由的过滤器。
**

Filter

过滤器-扩展自定义

Filter

:**

Filter

支持通过

spi

扩展。实现

GatewayFilter

Ordered

接口。
**

Filter

方法:** 过滤器处理逻辑。

getOrder

:定义优先级,值越大优先级越低。

过滤器的名称只需要写前缀,过滤器命名必须是

xxxGatewayFilterFactory

(包括自定义)。

全局过滤器示例: 创建一个全局过滤器类,这也是一个前置过滤器,实现

GlobalFilter

接口:

publicclassTokenFilterimplementsGlobalFilter,Ordered{Logger logger=LoggerFactory.getLogger(TokenFilter.class);@OverridepublicMono<Void>filter(ServerWebExchange exchange,GatewayFilterChain chain){String token = exchange.getRequest().getQueryParams().getFirst("token");if(token ==null|| token.isEmpty()){
            logger.info("token is empty...");
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);return exchange.getResponse().setComplete();}return chain.filter(exchange);// 先执行业务逻辑,在执行exchange,是前置过滤器}@OverridepublicintgetOrder(){// // 过滤器的执行顺序,值越小优先级越高return-100;}}

自定义路由过滤器示例: 创建自定义的路由过滤器,可以实现

GatewayFilter

接口:

importorg.springframework.cloud.gateway.filter.GatewayFilter;importorg.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;importorg.springframework.stereotype.Component;importorg.springframework.web.server.ServerWebExchange;importreactor.core.publisher.Mono;@ComponentpublicclassMyCustomFilterextendsAbstractGatewayFilterFactory<MyCustomFilter.Config>{publicMyCustomFilter(){super(Config.class);}@OverridepublicGatewayFilterapply(Config config){return(exchange, chain)->{// 前置过滤逻辑System.out.println("Custom Pre Filter executed");return chain.filter(exchange).then(Mono.fromRunnable(()->{// 限制性exchange再执行过滤器业务逻辑,是后期处理器。// 后置过滤逻辑System.out.println("Custom Post Filter executed");}));};}publicstaticclassConfig{// 配置属性}}

在配置文件中使用自定义过滤器:

spring:cloud:gateway:routes:-id: my_route
        uri: http://httpbin.org:80predicates:- Path=/get
        filters:-name: MyCustomFilter
标签: gateway 微服务 java

本文转载自: https://blog.csdn.net/zhengzhaoyang122/article/details/142833411
版权归原作者 程序猿进阶 所有, 如有侵权,请联系我们删除。

“SpringColoud GateWay 核心组件”的评论:

还没有评论