持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第8天,点击查看活动详情
负载均衡
我们只需要在9006中添加lb:// 服务名就可以显示负载均衡,例如 my-cloud-system 的 配置 lb://my-cloud-system
Predicate 断言
断言:当满足条件后才会进行转发路由,如果是多个,那么多个条件需要同时满足
官方提供断言的种类:docs.spring.io/spring-clou…
After
表示配置时间之后才进行转发时间戳获取代码,用于时间代码的获取:
- After=2022-10-25T15:47:07.849+08:00[Asia/Shanghai] #在这个时间之后的请求够可以进行通过,之前的则不能进行访问
Before
匹配ZonedDateTime类型的时间,表示匹配在指定日期时间之前的请求,之后的请求则拒绝404错误
Between
匹配ZonedDateTime类型的时间,由两个ZonedDateTime参数组成,第一个参数为开始时间,第二参数为结束时间,逗号进行分隔
Cookie
由两个参数组成,分别为name(Key)和regexp(正则表达式)(Value),匹配具有给定名称且其值与正则表达式匹配的Cookie。
路由规则会通过获取Cookie name值和正则表达式去匹配,如果匹配上就会执行路由,如果匹配不上则不执行。
- Cookie=cook-test,[a-z]+. # 匹配Cookie的key和value(正则表达式)表示任意字母
Header
由两个参数组成,第一个参数为Header名称,第二参数为Header的Value值,指定名称的其值和正则表达式相匹配的Header的请求
Header=headerName, \d+ # \d表示数字
Host
匹配当前请求是否来自于设置的主机。
Host=**.takeoff.com. #匹配当前的主机地址发出的请求
Method
可以设置一个或多个参数,匹配HTTP请求,比如POST,PUT,GET,DELETE
Method=POST,GET. #匹配POST,GET请求
Query
由两个参数组成,第一个为参数名称(必须),第二个为参数值(可选-正则表达式),匹配请求中是否包含第一个参数,如果有两个参数,则匹配请求中第一个参数的值是否符合第二个正则表达式。
Query=id,.+ # 匹配任意请求参数,这里如果需要匹配多个参数,可以写多个- Query=
RemoteAddr
参数由CIDR 表示法(IPv4 或 IPv6)字符串组成,也就是匹配的ID地址,
Weight
需要两个参数group和weight(int)权重数值,实现了路由权重功能,表示将相同的请求根据权重跳转到不同的uri地址,要求group的名称必须一致
routes:
- id: my-cloud-system_high #路由ID,没有固定要求,但是要保证唯一,建议配合服务名
uri: https://www.baidu.com/
predicates: # 断言
- Weight=groupName,8
- id: my-cloud-system_low #路由ID,没有固定要求,但是要保证唯一,建议配合服务名
uri: https://www.sogou.com/
predicates: # 断言
- Weight=groupName,2
直接访问http://localhost:8200/system/test/test可以看到我们请求的地址成8/2比例交替显示, 80% 的流量转发到www.baidu.com/,将约 20% 的流量转发到www.sogou.com/
Predicate就是为了实现一组匹配规则,让请求过来找到对应的Route进行处理。如果有多个断言则全部命中后进行处理
Filter
路由过滤器允许修改传入的HTTP请求或者返回的HTTP响应,路由过滤器的范围是特定的路由.
Spring Cloud GateWay 内置的Filter生命周期有两种:pre(业务逻辑之前)、post(业务逻辑之后)
GateWay本身自带的Filter分为两种: GateWayFilter(单一)、GlobalFilter(全局)
StripPrefix
StripPrefix 在我们当前请求中,通过规则值去掉某一部分地址,比如我们有一台服务中加入了一个前端nacos-provider想要通过这个去访问,我们在项目cloud-alibaba-nacos-9001中加入 context-path
server:
port: 9001
servlet:
context-path: /nacos-provider
现在9001的访问路径变为 http://localhost:9001/nacos-provider/mxn/hello,但是如果我们通过网关去访问路径就会变成http://localhost:9006/mxn/nacos-provider/mxn/hello这个时候我们通过这个路径去访问是访问不成功的,想要解决这个方法,这个就用到了我们 FIlter 中的 StripPrefix
routes:
- id: my-cloud-system
uri: lb://my-cloud-system
predicates:
- Path=/system/**
filters:
- StripPrefix=1 # 去掉地址中的第一部分
原来请求地址 http://localhost:8200/system/test/test 变为。 http://localhost:8200/test/test
自定义Filter
虽然Gateway给我们提供了丰富的内置Filter,但是实际项目中,自定义Filter的场景非常常见,因此单独介绍下自定义FIlter的使用。
想要实现GateWay自定义过滤器,那么我们需要实现 GatewayFilter 接口和 Ordered 接口
@Slf4j
@Component
public class TestFilter implements Ordered, GlobalFilter {
/**
* @Author: Take-off
* @Description: //TODO 过滤器-根据拿到的request和response return 是否放行
* @Date: 9:20 PM 2022/10/24
**/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//获取参数
String id = exchange.getRequest().getQueryParams().getFirst("id");
log.info("TestFilter请求时间:"+ new Date() + "--请求Id:" + id);
if(StringUtils.isEmpty(id)){
log.info("用户名不存在,非法请求!");
//如果username为空,返回状态码为401,需要代理身份验证
exchange.getResponse().setStatusCode(HttpStatus.PROXY_AUTHENTICATION_REQUIRED);
// 后置过滤器
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
/**
* @Author: Take-off
* @Description: //TODO 设定过滤器优先级,指越小优先级越高
* @Date: 9:21 PM 2022/10/24
**/
@Override
public int getOrder() {
return 0;
}
}
总结
对于GateWay的核心点主要有三个 Route、Predicate、Filter,我们搞懂了这三点,基本上对于GateWay的知识就掌握的差不多了,GateWay核心的流程就是:路由转发+执行过滤器链