一、Gateway创建动态路由 我们从gateway的配置文件application.yml中可以看到,url是固定的,并不能实现负载均衡,依然存在着问题。所以需要配置动态路由。即从注册中心动态创建路由的功能,利用微服务名进行路由。
server:
port: 9527spring:
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两个端口切换
二、断言Predicate 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: 9527spring:
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
三、过滤器Filter 路由过滤器可用于修改进入的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 错误请求
文章图片
文章图片
【微服务|springcloud微服务(二十四)-网关GateWay三大特性路由、断言、过滤器】
推荐阅读
- 框架底层原理|SpringIOC循环依赖底层原理
- 微服务架构概述
- 从建好到用好,阿里云原生微服务生态的演进
- 为什么Spring中每个Bean都要定义作用域()
- 基础|MyBatis框架知识点总结
- 中间件|(ElasticSearch02)day80分布式查漏补缺
- 微服务专题笔记|ElasticSearch——DSL查询及结果处理
- 构建一个简单的Spring Boot项目
- Java|springboot疫情防控核酸检测管理系统