SpringCloud - Spring Cloud 之 Gateway网关,Route路由,Predicate 谓词/断言,Filter 过滤器(十三)_spring.cloud.gateway.routes-CSDN博客
官网:Spring Cloud Gateway
工作原理:Spring Cloud Gateway
Glossary
-
Route: The basic building block of the gateway. It is defined by an ID, a destination URI, a collection of predicates, and a collection of filters. A route is matched if the aggregate predicate is true.
-
Predicate: This is a Java 8 Function Predicate. The input type is a Spring FrameworkServerWebExchange. This lets you match on anything from the HTTP request, such as headers or parameters.
-
Filter: These are instances of GatewayFilter that have been constructed with a specific factory. Here, you can modify requests and responses before or after sending the downstream request.
一、Route:路由
1)、正常路由
1、引入依赖
<!--引入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-gateway</artifactId>
</dependency>
2、修改配置文件:如果spring.cloud.gateway.discovery.locator.enabled设置true,Gateway启动时将注册中心查询到的所有服务,自动创建默认路由规则: 服务名/path
spring:
application:
name: gateway
cloud:
nacos:
server-addr: localhost:8848
gateway:
routes:
- id: user
uri: http://localhost:8083
predicates:
- Path=/user/**
filters:
- StripPrefix=1
discovery:
locator:
enabled: true #设置ture默认设置上面的route
2)、添加loadbalancer负载
1、添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
2、修改配置文件
spring:
application:
name: gateway
cloud:
nacos:
server-addr: localhost:8848
gateway:
routes:
- id: user
uri: lb://user #loadbalancer负载修改
predicates:
- Path=/user/**
filters:
- StripPrefix=1
discovery:
locator:
enabled: true
3)、整合nacos实现动态路由
1、nacos service配置创建gateway.yaml文件,保存gateway路由信息
2、引入配置
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
3、增加bootstrap.yaml配置
spring:
cloud:
nacos:
# nacos作为配置中心的地址
server-addr: localhost:8848
config:
file-extension: yaml
shared-configs[0]: # gateway.yaml
data-id: gateway.yaml
refresh: true
4、修改nacos service配置创建gateway.yaml文件,动态改变路由
5、原理:nacos修改配置文件->push客户端->nacos客户端调用NacosContextRefresher#registerNacosListener->发布RefreshEvent事件
->RefreshEventListener监听器->this#refresh#refresh() ->this#scoper#refreshAll()->发布RefreshScopeRefreshEvent事件:this#context#publishEvent(new RefreshScopeRefreshedEvent()) -> RouteRefreshListener监听器调用reset方法,发布RefreshRouteEnver事件
->CachingRouteLocator#onApplicationEvent完成路由规则的更新
简易版:nocos修改配置文件 -> push客户端 -> 客户端发布RefreshEvent事件、RefreshScopeRefreshEvent事件、RefreshRouteEnver事件 ->CachingRouteLocator完成本地缓存更新
3)、设置日志级别
logging:
level:
reactor.netty: debug
4)、设置actuator api:Spring Cloud Gateway
1、引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2、修改配置文件
management:
endpoints:
web:
exposure:
include: '*'
endpoint:
health:
show-details: always
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- Cookie=mycookie,mycookievalue
1)、完整扩展参数:Fully Expanded Arguments
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- name: Cookie
args:
name: mycookie
regexp: mycookievalue
2、路由断言工厂
1)、The After Route Predicate Factory:在指定事件之后的请求匹配
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
2)、The Before Route Predicate Factory:在指定事件之前的请求匹配
spring:
cloud:
gateway:
routes:
- id: before_route
uri: https://example.org
predicates:
- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
3)、The Between Route Predicate Factory:在指定事件之间的请求匹配
spring:
cloud:
gateway:
routes:
- id: between_route
uri: https://example.org
predicates:
- Between=2024-05-15T13:42:47.789-07:00[Asia/Shanghai], 2024-05-15T14:42:47.789-07:00[Asia/Shanghai]
4)、The Cookie Route Predicate Factory:带有指定Cookie名的请求匹配
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: https://example.org
predicates:
- Cookie=chocolate, ch.p
5)、The Header Route Predicate Factory:带有指定请求头的请求匹配
spring:
cloud:
gateway:
routes:
- id: header_route
uri: https://example.org
predicates:
- Header=X-Request-Id, \d+
6)、The Host Route Predicate Factory:带有指定host的请求匹配
spring:
cloud:
gateway:
routes:
- id: host_route
uri: https://example.org
predicates:
- Host=**.somehost.org,**.anotherhost.org
7)、The Method Route Predicate Factory:指定方法请求匹配
spring:
cloud:
gateway:
routes:
- id: method_route
uri: https://example.org
predicates:
- Method=GET,POST
8)、The Path Route Predicate Factory:指定请求路径请求匹配
spring:
cloud:
gateway:
routes:
- id: path_route
uri: https://example.org
predicates:
- Path=/red/{segment},/blue/{segment}
9)、The Query Route Predicate Factory:指定查询参数请求匹配
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=green
10)、The RemoteAddr Route Predicate Factory:指定远程调用ip请求匹配
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: https://example.org
predicates:
- RemoteAddr=192.168.1.1/24 #24 是子网掩码
11)、The Weight Route Predicate Factory:指定远程调用ip请求匹配:使用权重来路由相应请求,以下代码表示有80%的请求会被路由到weighthigh.org、20%会被路由到weightlow.org
spring:
cloud:
gateway:
routes:
- id: weight_high
uri: https://weighthigh.org
predicates:
- Weight=group1, 8
- id: weight_low
uri: https://weightlow.org
predicates:
- Weight=group1, 2
12)、The XForwarded Remote Addr Route Predicate Factory:指定请求X-Forwarded-For请求头匹配
spring:
cloud:
gateway:
routes:
- id: xforwarded_remoteaddr_route
uri: https://example.org
predicates:
- XForwardedRemoteAddr=192.168.1.1/24
13)、自定义断言
1、创建时间配置
@Data
public class JackTimeBetweenConfig {
private LocalTime begin;
private LocalTime end;
}
2、创建断言工厂
@Component
public class SkTimeBetweenRoutePredicateFactory extends AbstractRoutePredicateFactory<SkTimeBetweenConfig> {
public SkTimeBetweenRoutePredicateFactory() {
super(SkTimeBetweenConfig.class);
}
// 定义配置配与配置文件中的配置项的映射关系
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList("begin", "end");
}
@Override
public Predicate<ServerWebExchange> apply(SkTimeBetweenConfig config) {
// 获取配置文件中的配置值
LocalTime begin = config.getBegin();
LocalTime end = config.getEnd();
// full
return new Predicate<ServerWebExchange>() {
@Override
public boolean test(ServerWebExchange serverWebExchange) {
LocalTime now = LocalTime.now();
return now.isAfter(begin) && now.isBefore(end);
}
};
}
}
3、配置
spring:
cloud:
gateway:
routes:
- id: sktimebetween
uri: lb://user # 集成了loadbalancer 根据lb:// order名称进行服务发现和负载均衡得到一个结果值 http://localhost:9091/2/3 /order/query
predicates: # &&
- Path=/time/** # localhost:8090/jack/order/query
- SkTimeBetween=下午2:00,下午4:00
filters:
- StripPrefix=1
三、Filter:过滤器
1、局部过滤器
1)、AddRequestHeader GatewayFilter Factory:为请求添加请求头
2)、AddRequestParameter GatewayFilter Factory:为请求添加请求参数
3)、AddResponseHeader GatewayFilter Factory:为响应添加响应头
4)、RequestRateLimiter GatewayFilter Factory:请求限流
5)、StripPrefix GatewayFilter Factory:表示要从前截取的路径个数
6)、StripPrefix GatewayFilter Factory
....等等
1.1、自定义局部过滤器
1)、新增局部过滤器
@Slf4j
@Component
public class LogPrintGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
@Override
public GatewayFilter apply(NameValueConfig config) {
return ((exchange, chain) -> {
// 打印日志
log.info("打印日志...{},{}",config.getName(),config.getValue());
ServerHttpRequest request = exchange.getRequest().mutate().build();
return chain.filter(exchange.mutate().request(request).build());
});
}
}
2)、新增配置
filters:
- StripPrefix=1
- LogPrint=sk,18
2、全局过滤器
2.1、自定义全局过滤器
1)、新增自定义全局过滤器
@Component
public class CheckHeaderTokenGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String value = exchange.getRequest().getHeaders().getFirst("token");// 以token为key的值
if("token令牌".equals(value)){
return chain.filter(exchange);
}
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
// order值越小,执行的优先级就越高
@Override
public int getOrder() {
return 0;
}
}
2)、请求头token入参含有token令牌
五、与nginx网关差异
1、API 网关介绍
网关 = 路由转发 + 过滤器(geteway filler 和 global fillter)
角色:一个API架构,用来保护、增强、控制 对于API服务的访问,用来管理权限、访问控制、流量限制等
2、nginx
一个高性能的http和反向代理web服务器
3、geteway
微服务网关,统一路由、统一鉴权,跨域,限流等功能,springcloud gateway基于webflux框架实现
4、区别
1)、语言不同:nginx是c语言写的,gateway是java语言写的
2)、功能不同:nginx做总流量入口,反向代理,负载均衡等,还可以做web服务器;gateway做路由,断言,过滤器
3)、角色不同:nginx做反向代理、负载均衡;gateway做统一鉴权,负载均衡,服务发现