概念
- API Gateway,是系统的唯一对外的入口,介于客户端和服务器端之间的中间层,处理非业务功能 提供路由请求、鉴权、监控、缓存、限流等功能
- 统一接入
- 智能路由
- AB测试、灰度测试
- 负载均衡、容灾处理
- 日志埋点(类似Nignx日志)
- 流量监控
- 限流处理
- 服务降级
- 安全防护
- 鉴权处理
- 监控
- 机器网络隔离
主流的网关:
- zuul:是Netflix开源的微服务网关,和Eureka,Ribbon,Hystrix等组件配合使用,依赖组件比较多,性能教差
- kong: 由Mashape公司开源的,基于Nginx的API gateway
- nginx+lua:是一个高性能的HTTP和反向代理服务器,lua是脚本语言,让Nginx执行Lua脚本,并且高并发、非阻塞的处理各种请求
- springcloud gateway: Spring公司专门开发的网关,替代zuul
SpringCloud Gateway
- Spring官方出品,基于Spring5+Reactor技术开发的网关
- 性能强劲基于Reactor+WebFlux、功能多样
- 基于springboot2.x, 直接可以jar包方式运行
- 官方文档
https://spring.io/projects/spring-cloud-gateway
创建SpringCloud网关项目和依赖添加
- 添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
- 配置实战
server:
port: 8888
spring:
application:
name: api-gateway
cloud:
gateway:
routes: #数组形式
- id: order-service #路由唯一标识
uri: http://127.0.0.1:8000 #想要转发到的地址
order: 1 #优先级,数字越小优先级越高
predicates: #断言 配置哪个路径才转发
- Path=/order-server/**
filters: #过滤器,请求在传递过程中通过过滤器修改
- StripPrefix=1 #去掉第一层前缀
#访问路径 http://localhost:8888/order-server/api/v1/video_order/list
#转发路径 http://localhost:8000/order-server/api/v1/video_order/list
#需要过滤器去掉前面第一层
配置项怎么看?点击routes进去
SpringCloud Gateway网关整合Nacos
- 原先存在的问题
- 微服务地址写死
- 负载均衡没做到 - 添加Nacos服务治理配置
- 网关添加naocs依赖
<!--添加nacos客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
- 启动类开启支持
@EnableDiscoveryClient
- 修改配置文件
server:
port: 8888
spring:
application:
name: api-gateway
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
gateway:
routes: #数组形式
- id: order-service #路由唯一标识
#uri: http://127.0.0.1:8000 #想要转发到的地址
uri: lb://xdclass-order-service # 从nacos获取名称转发,lb是负载均衡轮训策略
predicates: #断言 配置哪个路径才转发
- Path=/order-server/**
filters: #过滤器,请求在传递过程中通过过滤器修改
- StripPrefix=1 #去掉第一层前缀
discovery:
locator:
enabled: true #开启网关拉取nacos的服务
## 访问路径 http://localhost:8888/order-server/api/v1/video_order/list
SpringCloud Gateway架构流程
- 路由:是网关的基本单元,由ID、URI、一组Predicate、一组Filter组成,根据Predicate进行匹配转发
route组成部分
id:路由的ID
uri:匹配路由的转发地址
predicates:配置该路由的断言,通过PredicateDefinition类进行接收配置。
order:路由的优先级,数字越小,优先级越高。
- 交互流程
- 客户端向Spring Cloud Gateway发出请求
- 如果网关处理程序映射确定请求与路由匹配
- 则将其发送到网关Web处理程序
- 通过特定过滤器链运行,前置处理-后置处理
Gateway内置的路由断言
-
什么是Gateway路由断言
- Predicate 来源于Java8,接受输入参数,返回一个布尔值结果
- Spring Cloud Gateway 中 Spring 利用 Predicate 的特性实现了各种路由匹配规则
- 转发的判断条件,SpringCloud Gateway支持多种方式,常见如:Path、Query、Method、Header等
- 支持多个Predicate请求的转发是必须满足所有的Predicate后才可以进行路由转发 -
内置路由断言介绍 RoutePredicateFactory 接口实现类
-
参数编写规则 XXXRoutePredicateFactory,使用XXX作为参数配置, 例如下面
predicates:
- Host=
- Path=
- Method=
- Header=
- Query=
- Cookie=
- Gateway内置的路由接口定时下线
需求:接口需要在指定时间进行下线,过后不可以在被访问
- 使用Before ,只要当前时间小于设定时间,路由才会匹配请求
- 东8区的2020-09-11T01:01:01.000+08:00后,请求不可访问
- 为了方便测试,修改时间即可
predicates:
- Before=2020-09-09T01:01:01.000+08:00
Gateway过滤器
- 过滤器生命周期
PRE: 这种过滤器在请求被路由之前调用,一般用于鉴权、限流等
POST:这种过滤器在路由到微服务以后执行,一般用于修改响应结果,比如增加header信息、打点结果日志 - 网关过滤器分类
- 局部过滤器GatewayFilter:应用在某个路由上,每个过滤器工厂都对应一个实现类,并且这些类的名称必须以 GatewayFilterFactory 结尾
- 全局过滤器:作用全部路由上,
-
内置很多局部过滤器,顶级接口 GatewayFilterFactory
-
内置很多全局过滤器,顶级接口 GlobalFilter
Gateway全局过滤器实现用户鉴权
- 自定义全局过滤器实现鉴权
@Component
public class UserGlobalFilter implements GlobalFilter,Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String token = exchange.getRequest().getHeaders().getFirst("token");
System.out.println(token);
if(StringUtils.isBlank(token)){
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
//继续往下执行
return chain.filter(exchange);
}
//数字越小,优先级越高
@Override
public int getOrder() {
return 0;
}
}
路径 :http://localhost:8888/order-server/api/v1/video_order/list?source=wechat
注意:网关不要加太多业务逻辑,否则会影响性能,务必记住