携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情
作者平台:
| CSDN:blog.csdn.net/qq_41153943…
| 知乎:www.zhihu.com/people/1024…
| GitHub:github.com/JiangXia-10…
| 微信公众号: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/product
predicates: #断言 用来配置路由规则
- Path=/product
- id: customer_router #路由对象唯一标识
uri: http://localhost:8085 #用来类别服务地址 http://localhost:8087/customer
predicates: #断言 用来配置路由规则
- Path=/customer
如果设置某个路径下所有的请求,则只需要修改配置:
Gateway的路由配置,除了可以通过上述的配置文件进行配置,还可以在项目中通过java代码的形式进行配置:
Gateway网关组件不仅可以实现路由的请求转发,还能够实现请求的负载均衡。
如果按照上述的配置文件进行路由配置,显然uri是写死的,所以无法实现负载均衡,所以需要对上述的配置进行改造。
由于该项目consul依赖中默认带有ribbon依赖,所以具有负载均衡的功能。
在gateway中实现负载均衡,只需要修改配置文件中的uri的配置即可:
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
*/
@Configuration
public class CustomizeGlobalFilter implements GlobalFilter, Ordered {
//类似于javaweb的dofilter方法
@Override
public 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
@Override
public int getOrder() {
return -1;
}
}
总结
上篇文章SpringCloud系列:服务网关组件Gateway(上)加上本篇文章的内容就是微服务项目中网关以及gateway网关的简单介绍,主要介绍了什么是网关,gateway网关的简单使用以及其核心的断言、过滤器以及自定义全局过滤器如何使用。更多的Gateway和网关的内容可以参考其官网,地址为:
如果有任何问题或者不正确的地方,欢迎指出、交流讨论!
最后本文的源码地址是:github.com/JiangXia-10… ,欢迎下载star!