网关简绍
就是网络的关口,负责请求的路由、转发、身份校验。
引入网关依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<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>
</dependencies>
配置路由规则
- id: 路由唯一标示
- uri: 路由目标地址
- predicates: 路由断言,判断请求是否符合当前路由
- filters: 路由过滤器,对请求或响应做特殊处理
spring:
application:
name: hm-gateway
cloud:
nacos:
server-addr: 127.0.0.1:8848
gateway:
routes:
- id: item-service # 路由的规则id, 自定义唯一
uri: lb://item-service # 路由服务目标 lb 代表负载均衡
predicates: # 路由断言, 判断路径是否符合规则。符合则路由到目标路径
- Path=/items/**,/search/** # 以请求路径做判断, 以/items 开头则符合
- id: user-service
uri: lb://user-service
predicates:
- Path=/users/**,/addresses/**
更多规则的路由断言
路由过滤器
使用 路由过滤器, 配置 AddRequestHeader 添加请求头
server:
port: 8080
spring:
application:
name: hm-gateway
cloud:
nacos:
server-addr: 127.0.0.1:8848
gateway:
routes:
- id: item-service
uri: lb://item-service
predicates:
- Path=/items/**,/search/**
filters:
- AddRequestHeader=truth, anyone long-press like button will be rich
- id: user-service
uri: lb://user-service
predicates:
- Path=/users/**,/addresses/**
使用 @RequestHeader(value = “truth”, required = false)String truth 获取
public void test(@RequestHeader(value = "truth", required = false)String truth) {
System.out.println("truth" + truth);
}
可以配置全局 默认过滤器, 使用 default-filters 与 routes 同级
server:
port: 8080
spring:
application:
name: hm-gateway
cloud:
nacos:
server-addr: 127.0.0.1:8848
gateway:
routes:
- id: item-service
uri: lb://item-service
predicates:
- Path=/items/**,/search/**
- id: user-service
uri: lb://user-service
predicates:
- Path=/users/**,/addresses/**
default-filters:
- AddRequestHeader=truth, anyone long-press like button will be rich
自定义过滤器
- GatewayFilter:路由过滤器,作用于任意指定的路由;默认不生效,要配置到路由后生效。
- GlobalFilter:全局过滤器,作用范围是所有路由;声明后自动生效。
过滤器处理流程
两种过滤器的过滤方法签名完全一致:
- ServerWebExchange 请求上下文, 包含整个过滤器链中共享数据
- GatewayFilterChain 过滤器链。当前过滤器执行完后,要调用过滤器链中的下一个过滤器
Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
GlobalFilter过滤器
定义Ordered 用来定义启动顺序全局执行过滤器, 实现 filter 来进行过滤信息
@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
System.out.println("GlobalFilter pre阶段 执行了。");
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}
GatewayFilter过滤器
自定义过滤器, 需要在配置文件中主动配置才能去调用, 同样也是实现 filter 来进行过滤的
@Component
public class PrintAnyGatewayFilterFactory extends AbstractGatewayFilterFactory {
@Override
public GatewayFilter apply(Object config) {
// 使用内部装饰类,定义启动顺序
return new OrderedGatewayFilter(new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("PrintAnyGateway 执行了");
return chain.filter(exchange);
}
}, 1);
}
}
具体配置文件
server:
port: 8080
spring:
application:
name: hm-gateway
cloud:
nacos:
server-addr: 127.0.0.1:8848
gateway:
routes:
- id: item-service
uri: lb://item-service
predicates:
- Path=/items/**,/search/**
- id: user-service
uri: lb://user-service
predicates:
- Path=/users/**,/addresses/**
default-filters:
- AddRequestHeader=truth, anyone long-press like button will be rich
- PrintAny
定义过滤器读取参数信息
server:
port: 8080
spring:
application:
name: hm-gateway
cloud:
nacos:
server-addr: 127.0.0.1:8848
gateway:
routes:
- id: item-service
uri: lb://item-service
predicates:
- Path=/items/**,/search/**
- id: user-service
uri: lb://user-service
predicates:
- Path=/users/**,/addresses/**
default-filters:
- AddRequestHeader=truth, anyone long-press like button will be rich
- PrintAny=1,2,3
从过滤器取 1,2,3, 配置全局 PrintAnyGatewayFilterFactory 将 Config 委托给父类, 使用 shortcutFieldOrder 按顺序取读取信息
@Component
public class PrintAnyGatewayFilterFactory extends AbstractGatewayFilterFactory<PrintAnyGatewayFilterFactory.Config> {
@Override
public GatewayFilter apply(Config config) {
// 使用内部装饰类,定义启动顺序
return new OrderedGatewayFilter(new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String a = config.getA();
String b = config.getB();
String c = config.getC();
System.out.println(a + b + c);
System.out.println("PrintAnyGateway 执行了");
return chain.filter(exchange);
}
}, 1);
}
@Data
public static class Config{
private String a;
private String b;
private String c;
}
public PrintAnyGatewayFilterFactory(){
super(Config.class);
}
@Override
public List<String> shortcutFieldOrder() {
return List.of("a", "b", "c");
}
}