作者平台:
| CSDN:https://blog.csdn.net/qq_41153943(ID:江夏、)
| 掘金:https://juejin.cn/user/651387938290686(ID:jiangxia_1024)
| 知乎:https://www.zhihu.com/people/1024-paper-96(ID:江夏)
| GitHub:https://github.com/JiangXia-1024?tab=repositories
| 微信公众号:1024笔记
本文一共2674字,预计阅读13分
前言
前面的文章SpringCloud系列:服务网关组件Gateway(上)介绍了网关的基本概念以及主要的网关组件Gateway。
Gateway服务网关组件可以理解为是所有服务的门户,能够将浏览器请求与服务端应用相分离,浏览器请求通过Gateway后由定义的路由和断言进行请求转发,路由代表需要转发请求的地址,断言相当于请求这些地址时所满足的条件,只有同时符合路由和断言才给予转发。所以Gateway网关可以理解等价于Router(路由)+Filter(过滤)。
今天继续学习Gateway服务网关在使用中的一些细节。
Gateway的使用
上一篇文章SpringCloud系列:服务网关组件Gateway(上)中简单介绍了如何在项目中使用Gateway进行路由转发,其核心就是在配置文件中进行Gateway的路由配置,如下:
gateway:routes:- id: product_router #路由对象唯一标识uri: http://localhost:8087 #用来类别服务地址 http://localhost:8087/productpredicates: #断言 用来配置路由规则- Path=/product- id: customer_router #路由对象唯一标识uri: http://localhost:8085 #用来类别服务地址 http://localhost:8087/customerpredicates: #断言 用来配置路由规则- Path=/customer
如果设置某个路径下所有的请求,则只需要修改配置:



Gateway网关组件不仅可以实现路由的请求转发,还能够实现请求的负载均衡。
如果按照上述的配置文件进行路由配置,显然uri是写死的,所以无法实现负载均衡,所以需要对上述的配置进行改造。
由于该项目consul依赖中默认带有ribbon依赖,所以具有负载均衡的功能。


lb即表示loadbalance的简写,加上服务注册中心注册的服务名。

网关中的断言和过滤
通过上述的配置文件,可以发现路由是 gateway中最基本的组件之一,一个主要包含了下面几个具体的信息:
id:它是路由标识符,用于区别于其他 Route;
uri:表示路由指向的目的地uri,即客户端的请求会被最终被转发到的微服务;
order:order可以用于多个路由之间的排序(升序),数值越小的路由排序越靠前,匹配的优先级越高。
predicate:断言的作用是进行条件判断,只有断言都返回真,才会真正的执行路由。断Predicate用于当请求到达网关时进行条件判断,只有断言都返回真,才会真正的执行路由。也就是表示在什么条件下才能进行路由转发,满足断言则放行请求,不满足则立即返回;
filter:过滤器用于修改请求和响应信息,当请求满足断言的所有条件之后,会向后端服务转发,在向后端服务转发之前会经过一些过滤,比如:

这里主要说说配置中的断言和过滤。Gateway的断言主要分为以下几种:
时间断言:用来判断请求时间在断言设置的时间之前(Before)、之后(After)还是之间(Between),比如:
predicates:- After=2022-07-26T21:02:47.789-07:00[Asia/Shanghai] # 之后- Before=2022-07-26T21:02:47.789-07:00[Asia/Shanghai] # 之前- Between=2022-07-26T21:02:47.789-07:00[Asia/Shanghai],2022-07-26T21:03:47.789-07:00[Asia/Shanghai] # 之间,两个时间段用,分开
Cookie/header作为匹配路由规则,比如下述表达表示如果请求携带的cookie/header中有token,且token的值为jiangxia将匹配当前路由,否则不匹配当前路由:
predicates:- Cookie=token,jiangxia- Header=token,jiangxia
Host作为匹配路由规则,比如下述的表达表示请求的url的顶级域名为com,二级域名中有jiangxia,三级域名随便(可以没有),端口为8081的请求匹配当前路由:
predicates:- Host=**.jiangxia.com:8081
Method请求方式作为路由匹配规则,比如下述表达表示Method请求方式为GET和POST的匹配路由规则:
predicates:- Method=GET,POST
Path路径作为匹配规则,比如下述表达表示请求路径为/jiangxia,后面可以没有或者包含多级路径的符合匹配规则:
predicates:- Path=/jiangxia/**
Query请求参数作为匹配规则,比如下面表示请求携带参数,且参数名为name的符合匹配规则:
predicates:- Query=name- Query=name,jiangxia # 携带参数参数名为name,且值为jiangxia
Weight权重作为匹配规则,匹配到的路由在同一组中按权重分发请求:
predicates:- Weight=group,10
以上就是断言predicate作为路由匹配规则的简单语法。filter过滤器的简单使用。
GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理。GatewayFilter Factories有30几个。
比如在配置文件中加入如下过滤器配置:
filters: #添加过滤器- AddRequestHeader=Name,jiangxia
AddRequestHeader就是其中一个过滤器名称,用来给路由对象的所有请求加入指定请求头信息中,后面的Name是key,jiangxia则是value
AddRequestParameter过滤器,用来给路由对象的所有转发请求加入指定的请求参数,比如:
filters: #添加过滤器- AddRequestParameter=Name,jiangxia
AddResponseHeader过滤器,用来给路由对象的所有转发请求的响应加入指定的头信息:
filters: #添加过滤器- AddResponseHeader=X-Response-Red,Blue
PrefixPath过滤器,用来给路由对象的所有转发请求的url加入指定的前缀信息,比如:
filters: #添加过滤器- PrefixPath=/mypath
浏览器访问的网关地址为/list,前缀路径为/mypath,转发到后端服务地址为:uri+前缀路径+地址栏地址,即uri/mypath/list
StripPrefix过滤器,用来给路由对象的所有转发请求的url去掉指定n个前缀,比如:
filters: #添加过滤器- StripPrefix=3 # 去掉3个前缀
比如浏览器访问网关地址:/list/product,StripPrefix=1,那么就变成了/product。
除了上面的自带的过滤器,gateway还支持自定义的全局filter,所有的请求都要经过全局过滤器之后再转发到后端服务,自定义filter只需要实现GlobalFilter和Ordered即可,并且重写filter和getOrder方法即可:
package com.jiangxia.filters;import org.springframework.cloud.gateway.filter.GatewayFilterChain;import org.springframework.cloud.gateway.filter.GlobalFilter;import org.springframework.context.annotation.Configuration;import org.springframework.core.Ordered;import org.springframework.http.server.reactive.ServerHttpRequest;import org.springframework.http.server.reactive.ServerHttpResponse;import org.springframework.web.server.ServerWebExchange;import reactor.core.publisher.Mono;/*** @author jiangxia* @date 2022年07月27日 21:02* 自定义网关全局filter*/@Configurationpublic class CustomizeGlobalFilter implements GlobalFilter, Ordered {//类似于javaweb的dofilter方法@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpRequest request = exchange.getRequest();ServerHttpResponse response = exchange.getResponse();System.out.println("经过了全局filter处理");Mono<Void> filter = chain.filter(exchange);//放行filter继续向后执行System.out.println("响应回来filter处理");return filter;}//排序:默认顺序按照自然顺序排序,-1则表示在所有的filter执行之前执行,即先执行自定的再执行配置文件设置的filter@Overridepublic int getOrder() {return -1;}}
总结
https://spring.io/projects/spring-cloud-gateway。
如果有任何问题或者不正确的地方,欢迎指出、交流讨论!
最后本文的源码地址是:https://github.com/JiangXia-1024/SpringCloudProject,欢迎下载star!
-END-
SpringCloud系列:OpenFeign组件 SpringCloud系列:服务雪崩、服务熔断、服务降级 SpringCloud系列:Hystrix熔断器组件的使用 SpringCloud系列:Hystrix Dashboard的简单使用 SpringCloud系列:服务网关组件Gateway(上)




