[TOC]
*****
# 1. Spring Cloud Gateway是什么?
```
1. 是Spring Cloud的网关(第二代),未来将会取代Zuul(第一代)
2. 基于Netty, Reactor以及WebFlux构建
3. 性能是Zuul的1.6倍, 参考: https://www.imooc.com/article/285068
4. 功能强大,内置了很多实用功能,比如转发 / 监控 / 限流等.
5. 设置优雅,容易扩展
缺点:
依赖Netty与WebFlux,不是Servlet编程模型;
不能在Servlet容器下工作,也不能构建成WAR包,只能构建成jar包;
不支持Spring Boot 1.x
```
# 2. 使用gateway搭建网关
代码参考: [ali-gateway-service 服务](https://gitee.com/lin_2019/alibaba-cloud/tree/master/ali-gateway-service)
```
注意: 不要引入spring-boot-starter-web包,会导致Gateway启动抛出异常,错误如下. 因为Spring Cloud Gateway 是使用 netty+webflux实现,webflux与web是冲突的.
Consider defining a bean of type 'org.springframework.http.codec.ServerCodecConfigurer' in your configuration.
```
# 3. Gateway的核心概念
```
源码:
Gateway Handler Mapping: org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping
Gateway Web Handler: org.springframework.cloud.gateway.handler.FilteringWebHandler
运行原理:
外部请求请求到Gateway, Gateway Handler Mapping会判断请求是否匹配路由的配置,
若匹配则交给Gateway Web Handler,它对读取路由上配置的过滤器,把请求交给过滤器做处理.
```
![](https://img.kancloud.cn/e1/ea/e1ea02c0764df029cca801522ff4a9c1_635x342.png)
```
1. Route(路由)
Spring Cloud Gateway的基础元素, 可简单理解成一条转发的规则.
包含: ID,目标URL, Predicate集合以及Filter集合.
2. Predicate(谓词/断言)
即 java.util.function.Predicate, Spring Cloud Gateway使用Predicate实现路由的匹配条件.
3. Filter(过滤器)
修改请求及相应
```
```
如图示例:
代表访问spring cloud gateway的 /users/1这个路径时,就会进入该路由,它会用AddRequestHeader这个过滤器做一些处理,
然后再把请求转发到uri指定的 http://www.itmuch.com
```
![](https://img.kancloud.cn/52/04/520409c83bff3c11dd2fbff8263d2b81_628x344.png)
# 4. 内置路由谓词工厂详解(RoutePredicateFactories)
```
路由谓词即条件 具体使用参考: https://www.imooc.com/article/290804
```
![](https://img.kancloud.cn/e1/ea/e1ea02c0764df029cca801522ff4a9c1_635x342.png)
# 5. 自定义路由谓词工厂
```
需求: 自定义谓词工厂 限制09:00 - 17:00才能访问
```
```
# 网关gateway配置
spring:
cloud:
gateway:
discovery:
locator:
# 让gateway通过服务发现组件找到其他微服务
enabled: true
# 配置路由
routes:
- id: after_route
uri: lb://ali-app-service
predicates:
# 当且仅当请求时的时间After配置的时间时,才会转发到用户微服务
# 目前配置不会进该路由配置,所以返回404
# 将时间改成 < now的时间,则访问localhost:8040/** -> user-center/**
# eg. 访问http://localhost:8040/users/1 -> user-center/users/1
# - After=2030-01-20T17:42:47.789-07:00[America/Denver]
# 自定义谓词工厂规则 http://localhost:9999/test?param=1
- TimeBetween=上午10:50,下午5:00
```
```
/**
* TimeBetweenRoutePredicateFactory = 配置文件中定义的名称(TimeBetween) + RoutePredicateFactory(约定)
* 自定义谓词路由工厂要以[RoutePredicateFactory]结尾
* TimeBetweenConfig配置类指配置文件中的配置 [9:00, 17:00]
*
* TimeBetween
*/
@Component
public class TimeBetweenRoutePredicateFactory extends AbstractRoutePredicateFactory<TimeBetweenConfig> {
public TimeBetweenRoutePredicateFactory() {
super(TimeBetweenConfig.class);
}
//
@Override
public Predicate<ServerWebExchange> apply(TimeBetweenConfig config) {
LocalTime startTime = config.getStart();
LocalTime endTime = config.getEnd();
return exchange -> {
LocalTime now = LocalTime.now();
return now.isAfter(startTime) && now.isBefore(endTime);
};
}
//控制配置类与配置文件的映射关系(start映射为9:00, end映射为17:00)
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList("start", "end");
}
}
@Data
public class TimeBetweenConfig {
private LocalTime start;
private LocalTime end;
}
```
# 6. 内置过滤器工厂详解(GatewayFilterFactories)
```
过滤器为请求及相应添加业务逻辑处理;
具体使用参考: https://www.imooc.com/article/290816
如: 配置
# 过滤器配置
filters:
- AddRequestParameter=foo, bar
可以断点打在 org.springframework.cloud.gateway.filter.NettyRoutingFilter#filter,就可以调试Gateway转发的具体细节
```
# 7. 自定义过滤器工厂【生命周期、自定义的方式、核心API、编码】
```
7-1. 过滤器生命周期
pre: Gateway转发请求之前
post: Gateway转发请求之后
```
```
7-2. 自定义过滤器工厂的方式
方式1. 继承AbstractGatewayFilterFactory, 配置形式如下图:
源码参考: org.springframework.cloud.gateway.filter.factory.RequestSizeGatewayFilterFactory
```
![](https://img.kancloud.cn/ae/fc/aefcd8e162651e0fb458d8bb07badb5c_566x406.png)
```
方式2. 继承AbstractNameValueGatewayFilterFactory, 配置形式如下图:
源码参考: org.springframework.cloud.gateway.filter.factory.AddRequestHeaderGatewayFilterFactory
```
![](https://img.kancloud.cn/7d/68/7d68b7e5b92672628c868b6ef9805851_702x291.png)
```
7-3. 核心API
exchange.getRequest().mutate().xxx //修改request请求
exchange..mutate().xxx //修改exchange
chain.filter(exchange) //传递给下一个过滤器处理
exchange.getResponse() //拿到响应
```
```
7-4. 编写一个过滤器工厂(注意: 新建类必须以[GatewayFilterFactory]结尾)
需求: 进入到过滤器工厂时,记录一下日志
注意: PreLogGatewayFilterFactory 的组成是配置文件中PreLog + GatewayFilterFactory,严格定义
@Slf4j
@Component
public class PreLogGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
@Override
public GatewayFilter apply(NameValueConfig config) {
return ((exchange, chain) -> {
//getName获取a, getValue获取b
log.info("请求进来了...{}, {}", config.getName(), config.getValue());
//修改请求
ServerHttpRequest modifiedRequest = exchange.getRequest().mutate().build();
//修改Exchange
ServerWebExchange modifiedExchange = exchange.mutate().request(modifiedRequest).build();
//处理完成传递给下一个过滤器处理
return chain.filter(modifiedExchange);
});
}
}
# 过滤器配置
filters:
- PreLog=a,b
```
# 8. 全局过滤器
```
参考: https://www.imooc.com/article/290821
```
# 9. 监控SpringCloudGateway
```
参考: https://www.imooc.com/article/290822
```
# 10. 排错、调试技巧总结【调试排错三板斧】
```
参考: https://www.imooc.com/article/290824
```
# 11. 过滤器执行顺序
`11-1. 执行顺序`
![](https://img.kancloud.cn/4f/96/4f969e58afcc32e66aec441208f90cf2_394x54.png)![](https://img.kancloud.cn/a6/ca/a6ca501fb2d786399ba9fda5209e9e25_649x323.png)![](https://img.kancloud.cn/86/d3/86d3a54bcf4444a3790b87f17b759e27_658x342.png)![](https://img.kancloud.cn/36/32/36322ec8ca063db57d426b8c088080ce_721x50.png)
`11-2. 自定义控制order`
```
@Slf4j
@Component
public class PreLogGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
@Override
public GatewayFilter apply(NameValueConfig config) {
GatewayFilter filter = ((exchange, chain) -> {
//getName获取a, getValue获取b
log.info("请求进来了...{}, {}", config.getName(), config.getValue());
//修改请求
ServerHttpRequest modifiedRequest = exchange.getRequest().mutate().build();
//修改Exchange
ServerWebExchange modifiedExchange = exchange.mutate().request(modifiedRequest).build();
//处理完成传递给下一个过滤器处理
return chain.filter(modifiedExchange);
});
//第二个参数就是定义order顺序的
return new OrderedGatewayFilter(filter, 1000);
}
}
```
# 12. 源码分析
![](https://img.kancloud.cn/ed/bb/edbbe4567480da8ece8752a7012dc61d_676x278.png)
# 13. SpringCloudGateway限流
```
参考: https://www.imooc.com/article/290828
```
# 生成漂亮的静态文档说明页
```
参考:http://www.itmuch.com/other/doc-generate/
```