1.微服务网关介绍
- 什么是网关
- API Gateway,是系统的唯一对外的入口,介于客户端和服务器端之间的中间层,处理非业务功能,提供路由请求、鉴权、监控、缓存、限流等功能
- 统一接入
- 智能路由
- AB测试、灰度测试
- 负载均衡、容灾处理
- 日志埋点(类似Nginx日志)
- 流量监控
- 限流处理
- 服务降级
- 安全防护
- 鉴权处理
- 监控
- 机器网络隔离
- 主流的网关
- zuul:是Netflix开源的微服务网关,和Eureka、Ribbon、Hystrix等组件配合使用,依赖组件比较多,性能较差
- kong:由Mashape公司开源的,基于Nginx的API gateway
- nginx+lua:是一个高性能的http和反向代理服务器,lua是脚本语言,让nginx执行lua脚本,并且高并发、非阻塞的处理各种请求
- springcloud gateway:spring公司专门开发的网关,替代zuul
- 注意:AlibabaCloud全家桶还没对应的网关,我们就用SpringCloud官方推荐的gateway
2.SpringCloud Gateway介绍
- 什么是SpringCloud Gateway
- Spring官方出品,基于Spring5+Reactor技术开发的网关
- 性能强劲,基于Reactor+WebFlux,功能多样
- 基于springboot2.x,可以直接jar包方式运行
- 官方文档:Spring Cloud Gateway
3.项目实战整合(nacos已经引入)
-
创建Gateway项目
-
添加依赖
xml<!--gateway--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency>
-
配置
yamlspring: application: name: gen-gateway-service cloud: # nacos注册中心地址 nacos: discovery: server-addr: 114.132.67.61:18848 gateway: # 数组形式 routes: # 用户服务,路由唯一标识 - id: user-service # 从nacos进行转发 uri: lb://gen-user-service # 优先级,数字越小优先级越高 order: 1 # 断言,配置哪个路径才转发,前端访问路径统一加上Path内容,网关判断转发对应的服务,如果是回调业务记得修改 predicates: - Path=/user-service/** # 过滤器,请求在传递过程中通过过滤器修改 filters: # 去掉第一层前缀,转发给后续的路径 - StripPrefix=1 discovery: locator: # 开启网关拉取nacos服务 enabled: true
-
4.Gateway配置和交互流程
-
网关配置项
-
路由:是网关的基本单元,由id、uri、一组predicate、一组filter组成,根据predicate进行匹配转发
route组成部分 id:路由的id uri:匹配路由的转发地址 predicates:配置该路由的断言,通过PredicateDefinition类进行接收配置 order:路由的优先级,数字越小优先级越高
-
-
交互流程
-
客户端向Spring Cloud Gateway发出请求
-
如果网关处理程序映射确定请求与路由匹配
-
则将其发送到网关Web处理程序
-
通过特定过滤器链运行,前置处理-后置处理
-
5.Gateway内置路由断言
-
什么是Gateway路由断言
- Predicate来源于Java8,接收输入参数,返回一个布尔值结果
- Spring Cloud Gateway中Spring利用Predicate的特性实现了各种路由匹配规则
- 转发的判断条件,Spring Cloud Gateway支持多种方式,常见如:Path、Query、Method、Header等
- 支持多个Predicate请求的转发是必须满足所有的Predicate后才可以进行路由转发
-
内置路由断言:RoutePredicateFactory接口实现类
-
参数编写规则:XXXRoutePredicateFactory,使用XXX作为参数配置,例如下面(部分代码)
yamlpredicates: - Path=/product-service/** # 实现接口定时下线功能,在配置时间后接口不可访问 - Before=2024-10-26T00:00:00.000+08:00
6.Gateway过滤器
-
过滤器生命周期
-
PRE:这种过滤器在请求被路由之前调用,一般用于鉴权、限流等
-
POST:这种过滤器在路由到微服务以后执行,一般用于修改响应结果,比如增加header信息、打点结果日志
-
-
网关过滤器分类
- 局部过滤器GatewayFilter:应用在某个路由上,每个过滤器工厂都对应一个实现类,并且这些类的名称必须以GatewayFilterFactory结尾
- 全局过滤器:作用于全部路由上
-
内置很多局部过滤器,顶级接口GatewayFilterFactory
-
内置很多全局过滤器,顶级接口GlobalFilter
-
自定义全局过滤器实现鉴权
javapackage com.gen.filter; import org.apache.commons.lang.StringUtils; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.Ordered; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; /** * 自定义全局过滤器实现鉴权功能 */ @Component public class LoginGlobalFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { String token = exchange.getRequest().getHeaders().getFirst("token"); // todo:业务逻辑 if (StringUtils.isBlank(token)) { exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); return exchange.getResponse().setComplete(); } // 继续往下执行 return chain.filter(exchange); } /** * 数字越小,优先级越高 * * @return */ @Override public int getOrder() { return 0; } }
-
注意:网关不要加太多业务逻辑,否则会影响性能