目录
1. Gateway概述
1.1 简介
Spring Cloud Gateway 是Spring Cloud的一个全新的API网关项目,替换了Zuul1。Gateway可以与Spring Cloud Discovery Client(如Eureka)、Ribbon、Hystrix等组件配合使用,实现路由转发、负载均衡、熔断等功能,并且Gateway还内置了限流过滤器,实现了限流的功能。Gateway基于Spring 5、Spring boot 2和Reactor构建,使用Netty作为运行时环境,比较完美的支持异步非阻塞编程。Netty使用非阻塞的IO,线程处理模型建立在主从Reactors多线程模型上。其中Boss Group轮询到新连接后与Client建立连接,生成NioSocketChannel,将channel绑定到Worker;Worker Group轮询并处理Read、Write事件。
1.2 用途
1) 反向代理。
2) 鉴权。
3) 流量控制。
4) 熔断。
5) 日志监控。
2. Gateway重要概念
1) Route(路由):路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由。
2) Predicate(断言):可以匹配HTTP请求中的所有内容(例如请求头和请求参数),如果请求与断言相匹配则进行路由。
3) Filter(过滤):指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或之后对请求进行修改。
3. Gateway案例
以下案例代码的Github地址。
三个modules分别是:cloud-eureka-server7001,cloud-gateway-gateway9527,cloud-provider-hystrix-payment8001,cloud-provider-hystrix-payment8002。
3.1 路由映射
1) 当前cloud-provider-hystrix-payment8001的接口(/payment/hystrix/ok/{id}):
@GetMapping("/payment/hystrix/ok/{id}")
public String paymentInfo_OK(@PathVariable("id") Integer id) {
String result = paymentService.paymentInfo_OK(id);
log.info("*****result: " + result);
return result;
}
测试结果:

2) cloud-gateway-gateway9527的路由映射核心配置(注意缩进):
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名称进行路由
routes:
- id: payment_route # 路由的id,没有规定规则但要求唯一,建议配合服务名
#匹配后提供服务的路由地址
uri: http://localhost:8001
predicates:
- Path=/payment/hystrix/** # 断言,路径相匹配的进行路由
- id: payment_route2
uri: http://localhost:8001
predicates:
- Path=/payment/lb/** #断言,路径相匹配的进行路由
测试结果:

3.2 路由两种配置方式
1) 第一种方式就是3.1提及到的yml配置方式(推荐)。
2) 第二种方式就是通过配置Bean(RouteLocator),当访问地址 http://localhost:9527/guonei时会自动转发到地址(http://news.baidu.com/guonei) :
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
RouteLocatorBuilder.Builder routes = builder.routes();
routes.route("path_route_eiletxie",
r -> r.path("/guonei")
.uri("http://news.baidu.com/guonei")).build();
return routes.build();
}
测试结果:

3.3 动态路由
1) 默认情况下Gateway会根据注册中心的服务列表,以注册中心上微服务名为路径创建动态路由进行转发,从而实现动态路由的功能。
2) cloud-gateway-gateway9527的application.yml加上:
- id: payment_route3
uri: lb://cloud-provider-hystrix-payment
predicates:
- Path=/payment/circuit/** # 断言,路径相匹配的进行路由
注:
- 不能和前面两个Route的Path有重合,否则会先匹配前面的Route。
- lb://serviceName是springcloud gateway在微服务中自动为我们创建的负载均衡uri(uri的协议为lb,表示启用Gateway的负载均衡功能)。
3) 启动cloud-eureka-server7001,然后启动cloud-provider-hystrix-payment8001, cloud-provider-hystrix-payment8002。

测试结果(8001/8002两个端口的切换):


3.4 Predicate的使用
Route Predicate Factories,简单来说,Predicate就是为了实现一组匹配原则,让请求过来找到对应的Route进行处理。
3.4.1 After Route Predicate
设置当前时间再加1小时进行测试,当测试请求的时间小于设定时间时就会报错,必须在 AFTER 某个时间以后请求才有效。
- id: payment_route01
uri: lb://cloud-payment-service
predicates:
- Path=/payment/hystrix/**
- After=2020-03-12T16:44:15.064+08:00[Asia/Shanghai]
3.4.2 Before Route Predicate
设置当前时间再加1小时进行测试,当测试请求的时间小于设定时间时就会报错,必须在 AFTER 某个时间以后请求才有效。
- id: payment_route02
uri: lb://cloud-payment-service
predicates:
- Path=/payment/hystrix/**
- Before=2020-03-12T16:44:15.064+08:00[Asia/Shanghai]
3.4.3 Between Route Predicate
- id: payment_route03
uri: lb://cloud-payment-service
predicates:
- Path=/payment/hystrix/**
- Between=2020-03-12T16:44:15.064+08:00[Asia/Shanghai], 2021-03-12T16:44:15.064+08:00[Asia/Shanghai]
3.4.4 Cookie Route Predicate
curl http://localhost:9527/payment/hystrix/ok/31 --cookie "username=bastriver"
- id: payment_route04
uri: lb://cloud-payment-service
predicates:
- Path=/payment/hystrix/**
#- After=2020-03-12T15:44:15.064+08:00[Asia/Shanghai]
- Cookie=username,bastriver
3.4.5 Header Route Predicate
curl http://localhost:9527/payment/hystrix/ok/31 -H "X-Request-Id:100"
- id: payment_route05
uri: lb://cloud-payment-service
predicates:
- Path=/payment/hystrix/**
- Header=X-Request-Id,\d+ #请求头要有 X-Request-Id属性并且值为整数的正则表达式
3.4.6 Host Route Predicate
curl http://localhost:9527/payment/hystrix/ok/31 -H "Host:bastriver.atguigu.com"
- id: payment_route06
uri: lb://cloud-payment-service
predicates:
- Path=/payment/hystrix/**
- Host=**.atguigu.com
3.4.7 Method Route Predicate
- id: payment_route08
uri: lb://cloud-payment-service
predicates:
- Path=/payment/hystrix/**
- Method=GET
3.4.8 Path Route Predicate
- id: payment_route08
uri: lb://cloud-payment-service
predicates:
- Path=/payment/hystrix/**
3.4.9 Query Route Predicate
curl http://localhost:9527/payment/hystrix/ok/31?username=31
- id: payment_route09
uri: lb://cloud-payment-service
predicates:
- Path=/payment/hystrix/**
- Query=username, \d+ # 要有参数名username并且值还要是正整数才能路由
3.5 Filter的使用
GatewayFilter Factories,总体上分为两类:GatewayFilter和GlobalFilter。
3.5.1 GatewayFilter
以AddRequestHeader为例,GatewayFilter Factory会在匹配的请求头加上一对请求头,名为X-Request-red 值为blue。
- id: payment_route10
uri: http://localhost:8001
predicates:
- Path=/payment/hystrix/**
filters:
- AddRequestHeader=X-Request-red, blue
3.5.2 自定义过滤器
为了实现全局日志记录和全局日志记录,通常需要自定义全局GlobalFilter。
1) 添加MyLogGatewayFilter(增加了Query参数的匹配,如果不包含uname就不能通过请求)。
@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);
}
/**
* 加载过滤器的顺序,数字越小,优先级越高
* @return
*/
@Override
public int getOrder() {
return 0;
}
}
2) 测试结果(localhost:9527/payment/hystrix/ok/1?uname=z3):


附:
2) demo中集成了Hystrix,如果需要了解相关的内容可以参考:关于Springcloud Hystrix的总结。
本文详细介绍了SpringCloud Gateway的功能和用途,包括作为API网关的角色,实现反向代理、鉴权、流量控制和熔断等。文章重点讲解了Gateway的重要概念,如路由、断言和过滤器,并通过实例展示了如何配置路由映射、动态路由、各种Predicate的使用以及过滤器的实现,包括自定义过滤器。此外,还提供了GitHub上的代码案例供读者参考。

589

被折叠的 条评论
为什么被折叠?



