我们从gateway的配置文件application.yml中可以看到,url是固定的,并不能实现负载均衡,依然存在着问题。所以需要配置动态路由。即从注册中心动态创建路由的功能,利用微服务名进行路由。
server:
port: 9527
spring:
application:
name: cloud-gateway-server
cloud:
gateway:
discovery:
locator:
enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
- id: payment_routh #路由的ID,没有固定规则但要求保持唯一
uri: lb://CLOUD-PAYMENT-SERVICE #匹配后提供的路由地址
predicates:
- Path=/payment/get/** #断言,路径相匹配的进行路由
- id: payment_routh2
uri: lb://CLOUD-PAYMENT-SERVICE #匹配后提供的路由地址
predicates:
- Path=/payment/lb/**
eureka:
client:
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka/
1.2 测试
启动Eureka,payment8001,payment8002,gateway9527
请求地址:http://localhost:9527/payment/lb
效果:8001/8002两个端口切换
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.
常用的Route Predicate
1. After Route Predicate
server:
port: 9527
spring:
application:
name: cloud-gateway-server
cloud:
gateway:
discovery:
locator:
enabled: true
routes:
- id: payment_routh #路由的ID,没有固定规则但要求保持唯一
uri: lb://CLOUD-PAYMENT-SERVICE #匹配后提供的路由地址
predicates:
- Path=/payment/get/** #断言,路径相匹配的进行路由
- After=2021-12-17T21:24:30.485+08:00[Asia/Shanghai]
- id: payment_routh2
uri: lb://CLOUD-PAYMENT-SERVICE #匹配后提供的路由地址
predicates:
- Path=/payment/lb/**
- After=2021-12-17T21:24:30.485+08:00[Asia/Shanghai]
eureka:
client:
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka/
请求只有在after之后的时间才会起作用,不到时间会报404
2. Before Route Predicate
3. Between Route Predicate
4. Cookie Route Predicate
5. Header Route Predicate
6. Host Route Predicate
7. Method Route Predicate
8. Path Route Predicate
9. Query Route Predicate
路由过滤器可用于修改进入的HTTP请求和返回的HTTP响应,路由过滤器只能指定路由进行使用。
Spring Cloud Gateway内置了多种路由过滤器,他们都由GatewayFilter的工厂 类来产生
生命周期:
1.pre
2.post
自定义过滤器:
自定义全局GlobalFilter
1.实现两个接口
@Component
@Slf4j
public class MyLogGlobalFilter implements GlobalFilter,OrderedFilter {
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("come in global filter: {}", new Date());
ServerHttpRequest request = exchange.getRequest();
String uname = request.getQueryParams().getFirst("uname");
if (uname == null) {
log.info("用户名为null,非法用户");
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
return exchange.getResponse().setComplete();
}
// 传递给下一个过滤器
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}
2.遇到的问题
别的教程都是这样配置,但是自定义的过滤器报错,报错Cannot access javax.servlet.Filter。所以又在pom中引入javax.servlet依赖。重写Filter的方法,问题解决。
javax.servlet
servlet-api
2.5
3. 测试
3.1 正确请求
3.2 错误请求