目录
4.4.2、实现GlobalFilter,OrderId两个接口
1、概念
1.1、作用
反向代理、鉴权、流量控制、熔断以及日志监控
1.2、微服务中网关位置
1.3、核心功能
1.3.1、路由(Route)
- 路由是构建网关的基本模块
- 由ID,目标URI,一系列的断言和过滤器组成
1.3.2、断言(Predicate)
- 开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数)
- 如果请求与断言相匹配则进行路由
1.3.3、过滤(Filter)
- 指的是Spring框架中GatewayFilter的实例
- 使用过滤器,可以在请求被路由前或者之后对请求进行修改.
1.4、Gateway工作流程
1.4.1、流程
1.客户端向Getway发出请求,然后在Gateway Handler Mapping中找到与请求匹配的路由,并发送到Gateway Web Handler
2.Handler再通过指定的过滤器链,将请求发送到实际的服务执行业务逻辑,然后返回。
1.4.2、过滤器链
- 发送代理请求之前(“pre”)作用:参数校验、权限校验、流量监控、日志输出和协议转换等。
- 发送代理请求之后(“post”)作用:响应内容、响应头修改、日志输出、流量监控等
2、Gateway使用
2.1、固定IP地址进行路由
2.1.1、POM文件
添加Gateway依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
2.1.2、yaml配置文件
server:
port: 9527
spring:
application:
name: cloud-gateway
eureka:
instance:
hostname: cloud-gateway-service
client:
service-url:
fetch-registry: true
register-with-eureka: true
defaultZone: http://eureka7001.com:7001/eureka/
2.1.3、业务类可以不添加业务类
2.1.4、主启动类
@SpringBootApplication
@EnableEurekaClient
public class GatewayMain9527 {
public static void main(String[] args) {
SpringApplication.run(GatewayMain9527.class, args);
}
}
2.1.5、添加匹配的路由地址
1)在yaml配置文件中添加
spring:
cloud:
gateway:
routes:
- id: payment_route # 路由的id,没有规定规则但要求唯一,建议配合服务名
uri: http://localhost:8001 #匹配后提供服务的路由地址
predicates:
- Path=/payment/get/** # 断言,路径相匹配的进行路由(**通配符)
- id: payment_route2
uri: http://localhost:8001
predicates:
- Path=/payment/lb/** #断言,路径相匹配的进行路由
2)代码中注入RouteLocator的Bean
1.新建配置类
2.在配置类中,配置路由地址
@Configuration
public class GateWayConfig {
/**
* 配置了一个id为route-name的路由规则
* 当访问地址http://localhost:9527/guonei时会自动转发到地址:http://news.baidu.com/guonei
* */
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder) {
RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
routes.route("path_rout_uclass", r -> r.path("/guonei")
.uri("http://news.baidu.com/guonei")).build();
return routes.build();
}
}
2.2、动态路由(利用微服务名称)
2.2.1、POM文件同2.1.1
2.2.2、yaml配置文件
1.开启动态路由功能
2.设置动态路由微服务名称(uri的协议lb,表示启用Gateway的负载均衡功能)
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
- id: payment_route # 路由的id,没有规定规则但要求唯一,建议配合服务名
#uri: http://localhost:8001 #匹配后提供服务的路由地址
uri: lb://cloud-payment-service # 匹配后提供服务的路由地址
predicates:
- Path=/payment/get/** # 断言,路径相匹配的进行路由(**通配符)
- id: payment_route2
#uri: http://localhost:8001
uri: lb://cloud-payment-service # 匹配后提供服务的路由地址
predicates:
- Path=/payment/lb/** #断言,路径相匹配的进行路由
eureka:
instance:
hostname: cloud-gateway-service
client:
service-url:
fetch-registry: true
register-with-eureka: true
defaultZone: http://eureka7001.com:7001/eureka/
3、断言(Predicate)
3.1、作用
一个请求在抵达网关层后,首先就要进行断言匹配,在满足所有断言之后才会进入Filter阶段
3.2、Gateway断言类型
1)时间片断言:
- After表示在xxx时刻之后,该路由有效
- Before表示在xxx时刻之前,该路由有效
- Between表示在两个时刻之间,该路由有效
- id: payment_route2
uri: lb://cloud-payment-service # 匹配后提供服务的路由地址
predicates:
- Path=/payment/lb/** #断言,路径相匹配的进行路由
- After=2020-02-21T16:51:37.485+08:00[Asia/Shanghai]
2)路径匹配(Path):在断言中填上一段URL匹配规则
- id: payment_route2
uri: lb://cloud-payment-service # 匹配后提供服务的路由地址
predicates:
- Path=/payment/lb/** #断言,路径相匹配的进行路由
3)Cookie断言:Cookie验证的是Cookie中保存的信息,需要连同属性值一起验证
- id: payment_route2
uri: lb://cloud-payment-service # 匹配后提供服务的路由地址
predicates:
- Cookie=username,zzyy
4)Method断言:即Get/Post,请求方式的匹配
5)RequestParam断言
- 属性名验证:此时断言只会验证QueryPrameters列表中某一属性是否存在
- 属性值验证:不仅会验证属性是否存在,还会验证它的值是不是和断言相匹配
6)Header断言:检查Header中是否包含了响应的属性,可以用来验证请求是否携带了访问令牌
7)Host断言:**.another.org,匹配域名列表,参数中的主机地址进行匹配
4、过滤器(Filter)
4.1、概念
用于修改进入的HTTP请求和返回的HTTP响应,路由过滤器只能指定路由进行使用。
4.2、分类
4.2.1、生命周期
- 发送代理请求之前(“pre”)作用:参数校验、权限校验、流量监控、日志输出和协议转换等。
- 发送代理请求之后(“post”)作用:响应内容、响应头修改、日志输出、流量监控等
4.2.2、作用范围
- 局部过滤器:作用于单个路由。
- 全局过滤器:不需要配置路由,系统初始化作用到所有路由上。
4.3、Gateway自带Filter
4.4、自定义过滤器
4.4.1、新建过滤器实现类
4.4.2、实现GlobalFilter,OrderId两个接口
1)public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain):过滤器实现逻辑
2)public int getOrder():加载过滤器的优先级,数字越小,优先级越高
@Component
@Slf4j
public class GateWayFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("come in 全局过滤器:" + new Date());
String uname = exchange.getRequest().getQueryParams().getFirst("uname");
if(uname == null){
log.info("非法用户");
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
//加载过滤器的优先级,数字越小,优先级越高
@Override
public int getOrder() {
return 0;
}
}