网关介绍
分布式架构存在的弊端
- 每个业务都会需要鉴权,限流、权限校验,跨域等逻辑。如果每个业务都各自为战,自己造轮子实现一遍,会很蛋疼,完全可以抽出来,放到一个统一的地方去做。
- 如果业务量比较简单的话,这种方式前端不会有什么问题。但随着业务量越来越复杂,比如淘宝等打开一个页面可能会涉及到数百个微服务协同工作,如果每一个微服务都分配一个域名的话,一方面客户端代码会很难维护,涉及到数百个域名,另一方面是连接数量的瓶颈。想象一下打开一个APP,通过抓包发现涉及到了数百个微服务远程调用,这在移动端下会显得非常低效
- 后期如果对微服务进行重构的话,也会变得非常麻烦,需要客户端配合你一起进行改造,比如商品服务,随着业务变得越来越复杂,后期需要进行拆分成多个微服务,这个时候对外部提供的服务也需要拆分成多个,同时前端也需要改变
所谓的API网关,就是指系统的统一入口,他分装了应用程序的内部结构,为客户端提供统一服务,一些与业务本身功能无关的公共逻辑可以在这里实现,诸如认证、鉴权,监控路由转发等。添加上API网关后,系统的架构图变成了如下所示:

Gateway介绍
网关作为流程的日寇,常用的功能包括路由转发,权限校验,限流等。
GateWay:是spring Cloud官方推出的第二代网关框架,提供更优秀的性能,具有更强大的功能。它是由WebFlux+Netty+Reactir实现的响应式API网关,它不能在传统的servlet容器中工作,也不能构建成war包。GateWay旨在为微服务架构提供一种简单并且有限的API路由管理方式,并基于Filter的方式提供网关的基本功能,例如说安全认证、监控、限流等。
核心概念
- 路由: 路由是网关中最基础的部分,路由的信息包括一个ID,一个目的URI,一个断言工厂,一组Filter组成。如果断言为真,则说明请求的路由和配置的路由匹配
- 断言: Java8中的断言函数,断言函数类型是spring5框架中的。断言函数允许开发者去定义匹配http/httpss中request的任何信息,比如请求头和参数等
- Filter: 可以对请求和响应进行处理
工作原理
初体验
添加依赖
<!--添加gateway的依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency>
修改yaml文件
server:port: 8886spring:application:name: api-gatewaycloud:# 配置相关的gateway配置# 配置路由规则gateway:routes:- id: order_route #路由的唯一标识,路由到order服务上uri: http://localhost:8010 #需要转发的地址#断言规则,用于路由规则匹配predicates:- Path=/order-serv/** #需要匹配的路径filters:- StripPrefix=1 # 转发之前,去掉第一层的内容
gateway整合nacos
引入nacos注册与发现的依赖
<!--nacos服务器的注册与发现--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>
配置yaml文件
server:port: 8886spring:application:name: api-gatewaycloud:nacos: # 配置nacos发现的相关信息discovery:server-addr: 111.229.181.158:8847username: nacospassword: nacos# 配置相关的gateway配置# 配置路由规则gateway:routes:- id: order_route #路由的唯一标识,路由到order服务上uri: lb://order-service #改成对应服务的服务名。使用nacos中本地负载均衡策略#断言规则,用于路由规则匹配predicates:- Path=/order-serv/** #需要匹配的路径filters:- StripPrefix=1 # 转发之前,去掉第一层的内容
使用简写的配置,自动寻找服务器
server:port: 8886spring:application:name: api-gatewaycloud:nacos: # 配置nacos发现的相关信息discovery:server-addr: 111.229.181.158:8847username: nacospassword: nacos# 配置相关的gateway配置# 配置路由规则gateway:discovery:locator:enabled: true #自动识别nacos的服务#routes:# - id: order_route #路由的唯一标识,路由到order服务上# uri: lb://order-service #改成对应服务的服务名。使用nacos中本地负载均衡策略#断言规则,用于路由规则匹配# predicates:# - Path=/order-serv/** #需要匹配的路径# filters:# - StripPrefix=1 # 转发之前,去掉第一层的内容
内置路由断言工厂
当请求gateway的时候,使用断言对请求进行匹配,如果匹配成功就路由转发,请求失败就返回404
基于DateTime类型的断言工厂
- AfterRoutePreducateFactory:接收一个日期参数,判断请求日期是否晚于指定日期
- BeforeRoutePreducateFactory:接收一个日期参数,判断请求日期是否早于指定日期
- BetweenRoutePreducateFactory:接收两个日期参数,判断请求日期是否在指定的时间段内
- After=
- 基于远程地址的断言工厂
RemoteAddrRoutePredicateFactory:接收一个IP地址端,判断请求主机地址是否在地址段中- RemoteAddr=192.168.1.1/24 - 基于cookie的断言工厂
CookieRiytePreducateFactory:接收两个参数,cookie名字和一个正则表达式,判断请求
-Cookie-chocloate, ch. - 基于header的断言工厂
HeaderRiytePreducateFactory - 基于Host的断言工厂
- 基于Method请求方法的断言工厂
自定义路由断言工厂
自定义路由断言工厂需要继承AbstractRoutePredicateFactory类,重写apply方法的逻辑。在apply方法中可以通过exchange.getRequest()拿到ServeltHttpRequest对象,从而可以获取到请求的参数,请求方式、请求头等信息
注意:命名需要以RoutePredicateFactory结尾,并且使用@Component注解加入到组件中
局部(内置、自定义)过滤器
跟自定义的断言工厂形式差不多
全局过滤器

局部过滤器是针对某个路由的,全局过滤器是针对所有路由请求的。
局部过滤器需要在路由中配置,全局路由器一旦定义了就会投入使用
自定义全局过滤器
需要实现GlobalFilter接口,并且注入到spring容器中
请求日志记录&跨域处理
React Netty访问日志需要设置:``
他必须通过Java系统属性,而不是Spring Boot配置的
GateWay的跨域请求
server:port: 8886spring:application:name: api-gatewaycloud:nacos: # 配置nacos发现的相关信息discovery:server-addr: 111.229.181.158:8847username: nacospassword: nacos# 配置相关的gateway配置# 配置路由规则gateway:globalcors:# discovery:# locator:# enabled: true #自动识别nacos的服务routes:- id: order_route #路由的唯一标识,路由到order服务上uri: lb://order-service #改成对应服务的服务名。使用nacos中本地负载均衡策略#断言规则,用于路由规则匹配predicates:- Path=/order-serv/** #需要匹配的路径filters:- StripPrefix=1 # 转发之前,去掉第一层的内容# 配置跨域的信息cors-configurations:'[/**]': # 允许跨域访问的资源allowedOrigins: "*" # 允许跨域的来源allowedMehtods:- GET- POST- DELETE- PUT- OPTION
整合sentinel流控降级
添加依赖
<!--引入sentinel-gateway的依赖--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId></dependency><!--引入sentinel的依赖--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency>
添加配置
# 配置dashbaord的控制台sentinel:transport:dashboard: 111.229.181.158:8847
