一文学习和掌握网关SpringCloudGateway
目录
- 什么是网关,网关的作用
- 网关工作过程
- 网关服务搭建
- 路由断言
- 路由过滤
- 自定义路由过滤器
什么是网关,网关的作用
通俗的讲,网关就是一个网络的看门的大爷,请求消息从一个网络传递到另一个网络,在微服务架构体系中,不再是直接打到目标服务的服务器实例上,而是直接与目标网络的网关建立连接,将请求消息首先传递到网关,注意的是网关不是一个网络设备,而是一个微服务,网关接收到请求消息后,可以进行数据校验,校验通过后,可能将一些其他有用的信息放在请求头上(路由过滤),然后根据请求消息中的请求路径进行请求转发(路由断言),具体的说就是从nacos中拉取实例列表,根据负载均衡挑选一个实例,将请求消息转发到目标服务实例上。
网关工作过程
- 客户端请求进入网关后由HandlerMapping对请求做判断,找到与当前请求匹配的路由规则(Route),然后将请求交给WebHandler去处理
- WebHandler则会加载当前路由下需要执行的过滤器链(Filter chain),然后按照顺序逐一执行过滤器(后面称为Filter)
- 图中Filter被虚线分为左右两部分,是因为Filter内部的逻辑分为pre和post两部分,分别会在请求路由到微服务之前和之后被执行。
- 只有所有Filter的pre逻辑都依次顺序执行通过后,请求才会被路由到微服务。
- 微服务返回结果后,再倒序执行Filter的post逻辑。
- 最终把响应结果返回。
网关服务搭建
1. 引入依赖
<!--网关--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><!--nacos discovery--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--负载均衡--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency>
2. 配置网关路由(路由断言和路由过滤)
路由断言和路由过滤是配置网关的核心功能,
- 路由断言是精准匹配当前请求需要转发到哪个微服务
- 路由过滤是请求消息、响应消息的动态处理,包括添加请求头,修改URL路径等等,支持全局过滤器和局部过滤器,全局过滤器是所有路由都生效,也可以单独配置某一个路由的过滤规则(局部路由);可以使用gateway的内置过滤器,也可以自定义路由过滤器,并配置在某一个路由或者全局配置。
server:port: 8080
spring:application:name: gatewaycloud:nacos:server-addr: 192.168.150.101:8848gateway:default-filters: # 全局过滤器- AddResponseHeader=X-Gateway-Default, true #为所有路由的请求消息添加请求头routes:- id: item # 路由规则id,自定义,唯一uri: lb://item-service # 路由的目标服务,lb代表负载均衡,会从注册中心拉取服务列表predicates: # 路由断言,判断当前请求是否符合当前规则,符合则路由到目标服务- Path=/items/**,/search/** # 这里是以请求路径作为判断规则filters: #局部路由过滤- StripPrefix=1[1,2,4](@ref)- id: carturi: lb://cart-servicepredicates:- Path=/carts/**
路由断言
网关支持的路由断言类型有很多,不过常用的就是Path,根据请求路径断言,进而转发
路由过滤
- 上文我们说过,网关的过滤器分为两种,内置的过滤器和自定义过滤器,无论是内置的过滤器还是自定义过滤器可以配置到某一个路由中,也可以配置成全局路由,这样所有的路由都会走该过滤器,内置路由可以参考官方文档网关内置路由
- 如果内置过滤器不满足需求,我们还可以自定义过滤器。
自定义路由过滤器
自定义路由过滤器分为两种
- GatewayFilter:路由过滤器,作用范围比较灵活,可以配置到某个路由作为局部过滤器,也可以配置成全局路由器,但是必须手动配置,不配置不生效。
- GlobalFilter:全局过滤器,作用范围是所有路由,不需手动配置,声明即生效。
实际开发工作中,GlobalFilter用的比较多,GatewayFilter用的比较少,下面主要说一下GlobalFilter的开发过程。主要是实现两个接口,GlobalFilter, Ordered
,其中Ordered
接口的目的是指定我们开发的过滤器在过滤器链中的执行时机,因为需要保证在NettyRoutingFilter
过滤器之前执行才可以
/*** 处理请求并将其传递给下一个过滤器* @param exchange 当前请求的上下文,其中包含request、response等各种数据* @param chain 过滤器链,基于它向下传递请求* @return 根据返回值标记当前请求是否被完成或拦截,chain.filter(exchange)就放行了。*/
@Component
public class PrintAnyGlobalFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {// 编写过滤器逻辑System.out.println("未登录,无法访问");// 要不放行,要不拦截//添加请求头并放行ServerHttpRequest newRequest = exchange.getRequest().mutate().header("X-User", "Alice") // 添加新头.build();ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();return chain.filter(exchange);// 拦截ServerHttpResponse response = exchange.getResponse();response.setRawStatusCode(401);return response.setComplete();}@Overridepublic int getOrder() {// 过滤器执行顺序,值越小,优先级越高return 0;}
}