手把手教你入侵网站修改数据,建设校园网站意义,哪个网站可以上传设计的作品,网站制作网免费优质博文#xff1a;IT-BLOG-CN
【1】Route路由#xff1a; Gateway的基本构建模块#xff0c;它由ID、目标URL、断言集合和过滤器集合组成。如果聚合断言结果为真#xff0c;则匹配到该路由。
Route路由-动态路由实现原理#xff1a; 配置变化Apollo 服务地址实例变化…优质博文IT-BLOG-CN
【1】Route路由 Gateway的基本构建模块它由ID、目标URL、断言集合和过滤器集合组成。如果聚合断言结果为真则匹配到该路由。
Route路由-动态路由实现原理 配置变化Apollo 服务地址实例变化Nacos。Spring Cloud Gateway通过RouteDefinitionLocator和RouteRefreshListener等组件实现动态路由。
先看下配置信息方便后面原理的理解SpringCloudGateway bootstrap.yml的配置如下
spring:application:name: gateway-servicecloud: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: true
apollo:bootstrap:namespaces: application # 1、登录 Apollo 控制台。 2、创建一个新的配置例如 application.yml。 3、内容就是上看配置的SpringCloud Gateway 配置的路由信息1、RouteDefinitionLocatorSpring 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: 8080
spring:application:name: api-gatewaycloud:gateway:routes:- id: gateway-serviceuri: https://www.baidu.comorder: 0predicates:- After2017-01-20T17:42:47.789-07:00[America/Denver]- Host**.foo.org- Path/headers- MethodGET- HeaderX-Request-Id, \d- Queryfoo, ba.- Querybaz- Cookiechocolate, ch.p在上面的配置文件中配置了服务的端口为8080配置spring cloud gateway相关的配置id标签配置的是router的id每个router都需要一个唯一的iduri配置的是将请求路由到哪里本案例全部路由到https://www.baidu.com。
Predicates After2017-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读者可以自行查阅官方文档再次不再演示。
Querybaz Query的值以键值对的方式进行配置这样在请求过来时会对属性值和正则进行匹配匹配上才会走路由。经过测试发现只要请求汇总带有baz参数即会匹配路由[localhost:8080?bazxid2]不带baz参数则不会匹配。
Queryfoo, ba.这样只要当请求中包含foo属性并且参数值是以 ba开头的长度为三位的字符串才会进行匹配和路由。使用curl测试命令行输入curl localhost:8080?foobab测试可以返回页面代码将foo的属性值改为babx再次访问就会报404证明路由需要匹配正则表达式才会进行路由。
HeaderX-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过滤器方案一写死在代码中
Bean
public RouteLocator customRouteLocator(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-servicepredicates:- Path/order/**filters:- ValidateCodeGatewayFilterFilter过滤器Filter按处理顺序Pre Filter / Post Filter Filter按作用范围分为 GlobalFilter全局过滤器。GatewayFilter 指定路由的过滤器。 Filter过滤器-扩展自定义Filter Filter支持通过spi扩展。实现GatewayFilterOrdered接口。 Filter方法 过滤器处理逻辑。getOrder定义优先级值越大优先级越低。 过滤器的名称只需要写前缀过滤器命名必须是xxxGatewayFilterFactory包括自定义。 全局过滤器示例 创建一个全局过滤器类这也是一个前置过滤器实现GlobalFilter接口
public class TokenFilter implements GlobalFilter, Ordered {Logger loggerLoggerFactory.getLogger( TokenFilter.class );Overridepublic MonoVoid 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是前置过滤器}Overridepublic int getOrder() {// // 过滤器的执行顺序值越小优先级越高return -100;}
}自定义路由过滤器示例 创建自定义的路由过滤器可以实现GatewayFilter接口
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;Component
public class MyCustomFilter extends AbstractGatewayFilterFactoryMyCustomFilter.Config {public MyCustomFilter() {super(Config.class);}Overridepublic GatewayFilter apply(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);}));};}public static class Config {// 配置属性}
}在配置文件中使用自定义过滤器
spring:cloud:gateway:routes:- id: my_routeuri: http://httpbin.org:80predicates:- Path/getfilters:- name: MyCustomFilter