视频链接:2020最新版SpringCloud框架开发教程-周阳
文章源码:https://github.com/geyiwei-suzhou/cloud2020/
动态路由
默认情况下,Gateway会根据注册中心注册的服务列表,以注册中心上微服务名为路径创建动态路由进行转发,从而实现动态路由的功能
启动:cloud-eureka-server7001、cloud-provider-payment8001、cloud-provider-payment8002 三个模块
cloud-gateway-gateway9527模块
修改pom文件
在gateway节点下添加新的子节点
discovery:
locator:
enabled: true # 开启从注册中心动态创建路由功能,利用微服务名进行路由
并将routes下的路由uri改为服务名地址
uri: lb://cloud-payment-service # 匹配后提供服务的路由地址
启动:cloud-gateway-gateway9527
访问:http://localhost:9527/payment/lb,刷新看一下效果吧
总结:动态路由就是为了实现路由资源的动态绑定,以服务名代替实际地址
断言
cloud-gateway-gateway9527模块
Gateway服务启动日志可以看到一系列Predicate Factory相关信息
gateway-request-predicates-factories
2021-01-07 14:02:06.278 INFO 34443 --- [ restartedMain] c.n.c.sources.URLConfigurationSource : To enable URLs as dynamic configuration sources, define System property archaius.configurationSource.additionalUrls or make config.properties available on classpath.
2021-01-07 14:02:06.707 INFO 34443 --- [ restartedMain] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [After]
2021-01-07 14:02:06.707 INFO 34443 --- [ restartedMain] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [Before]
2021-01-07 14:02:06.708 INFO 34443 --- [ restartedMain] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [Between]
2021-01-07 14:02:06.708 INFO 34443 --- [ restartedMain] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [Cookie]
2021-01-07 14:02:06.708 INFO 34443 --- [ restartedMain] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [Header]
2021-01-07 14:02:06.708 INFO 34443 --- [ restartedMain] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [Host]
2021-01-07 14:02:06.708 INFO 34443 --- [ restartedMain] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [Method]
2021-01-07 14:02:06.708 INFO 34443 --- [ restartedMain] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [Path]
2021-01-07 14:02:06.708 INFO 34443 --- [ restartedMain] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [Query]
2021-01-07 14:02:06.708 INFO 34443 --- [ restartedMain] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [ReadBodyPredicateFactory]
2021-01-07 14:02:06.708 INFO 34443 --- [ restartedMain] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [RemoteAddr]
2021-01-07 14:02:06.708 INFO 34443 --- [ restartedMain] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [Weight]
2021-01-07 14:02:06.708 INFO 34443 --- [ restartedMain] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [CloudFoundryRouteService]
Spring Cloud Gateway将路由匹配作为Spring WebFlux HandlerMapping基础架构的一部分
Spring Cloud Gateway包括许多内置的Route Predicate工厂。所有这些Predicate都与HTTP请求的不同属性匹配。多个Route Predicate工厂进行组合
Spring Cloud Gateway创建Route对象时,使用RoutePredicateFactory创建Predicate对象,Predicate对象可以赋值给Route。Spring Cloud Gateway包含许多内置的Route Predicate Factories
这些所谓的谓词都匹配HTTP请求的不同属性。多种谓词工厂可以组合,通过逻辑and
下面是RoutePredicateFactory类图
Gateway支持如下Predicate类型,在Pom文件中Predicate节点下即可:
- After Route Predicate:
- After
,如:- After=2021-01-07T14:35:08.693+08:00[Asia/Shanghai] - Before Route Predicate:
- Before
,如:- Before`=2021-01-07T14:35:08.693+08:00[Asia/Shanghai] - Between Route Predicate:
- Between
,如:- Between=2021-01-07T14:35:08.693+08:00[Asia/Shanghai], 2021-01-08T14:35:08.693+08:00[Asia/Shanghai] - Cookie Route Predicate:
- Cookie
,如:- Cookie=username, zzyy
Cookie Route Predicate需要两个参数,一个是Cookie name,一个是正则表达式。路由规则会通过获取对应的Cookie name值和正则表达式去匹配,如果匹配上就会执行路由,如果没有匹配则不执行 - Header Route Predicate:
- Header
,如:- Header=X-Request-Id, \d+ - Host Route Predicate:
- Host
,如:- Host=**.antherd.com - Method Route Predicate:
- Method
,如:- Method=GET - Path Route Predicate:
- Path
,如:- Path=/payment/** - Query Route Predicate:
- Query
,如:- Query=username, \d # 要有参数名username并且值必须是正数才能路由
关于时间参数,可以用如下代码生成范例
import java.time.ZonedDateTime;
public class T1 {
public static void main(String[] args) {
ZonedDateTime zonedDateTime = ZonedDateTime.now();
System.out.println(zonedDateTime);
# 2021-01-07T14:35:08.693+08:00[Asia/Shanghai]
}
}
部分curl测试命令
curl http://localhost:9527/payment/lb --cookies "username=zzyy"
curl http://localhost:9527/payment/lb --H "X-Request-Id:123"
curl http://localhost:9527/payment/lb --H "Host:www.antherd.com"
总结:Predicate就是为了实现一组匹配规则,让请求过来找到对应的Route进行处理
过滤器
GatewayFilter Factories路由过滤器可用于修改进入的HTTP请求和返回的HTTP响应,路由过滤器只能指定路由进行使用
Spring Cloud Gateway内置了多种路由过滤器,他们都由GatewayFilter的工厂类类产生
生命周期:pre 和 post
种类:GatewayFilter 、GlobalFilter 和 自定义过滤器
自定义过滤器
cloud-gateway-gateway9527模块
新建类:com.antherd.springcloud.filter.MyLogGatewayFilter
package com.antherd.springcloud.filter;
import java.util.Date;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
@Slf4j
public class MyLogGatewayFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("***** come in MyLogGatewayFilter:" + new Date());
String uname = exchange.getRequest().getQueryParams().getFirst("uname");
if (uname == null) {
log.info("***** 用户名为null,非法用户,o(╥﹏╥)o");
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}
启动:cloud-eureka-server7001,cloud-provider-payment8001,cloud-provider-payment8002,cloud-gateway-gateway9527 四个模块
访问:http://localhost:9527/payment/lb?uname=z3、http://localhost:9527/payment/lb 看一下效果
总结:Gateway的过滤器功能主要用于日志及权限管理