day_3 分布式入门: Gateway
Gateway
功能

依赖导入
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
除此之外也需要加入nacos-discovery依赖,用于发现注册过的服务。
基础原理

多个路由规则共存时,会按照顺序进行匹配,一旦匹配到就不再进行,而是转发请求,匹配顺序也可以通过order属性进行配置
路由规则
通过配置文件
通过添加类似如下的配置,可以设置路由规则:
spring:
cloud:
gateway:
routes:
- id: order-route
uri: lb://service-order
predicates:
- Path=/api/order/**
- id: product-route
uri: lb://service-product
predicates:
- Path=/api/product/**
其中lb://service-order的uri为启用负载均衡,这也需要加入loadBalancer依赖
不过由于
GatewayProperties也是通过@ConfigurationProperties注解过的配置类,那么在启用@EnableConfigurationProperties后,它也可以通过Nacos配置中心来动态配置路由。
断言规则

自定义断言规则示例
@Component
public class VipRoutePredicateFactory extends AbstractRoutePredicateFactory<VipRoutePredicateFactory.Config> {
public static final String PARAM_KEY = "param";
public static final String VALUE_KEY = "value";
public VipRoutePredicateFactory() {
super(Config.class);
}
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList(PARAM_KEY, VALUE_KEY);
}
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return (GatewayPredicate) exchange -> {
ServerHttpRequest request = exchange.getRequest();
String first = request.getQueryParams().getFirst(config.param);
return StringUtils.hasText(first) && first.equals(config.value);
};
}
@Validated
public static class Config {
@NotEmpty String param;
String value;
public VipRoutePredicateFactory.Config setParam(String param) {
this.param = param;
return this;
}
public VipRoutePredicateFactory.Config setValue(String value) {
this.value = value;
return this;
}
}
}
过滤器

过滤器Filter
spring:
cloud:
gateway:
routes:
- id: product-route
uri: lb://service-product
predicates:
- Path=/api/product/**
filters:
- RewritePath=/api/product/?(?<val>.*), /$\{val}
- id: order-route
uri: lb://service-order
predicates:
- Path=/api/order/**
filters:
- RewritePath=/api/order/?(?<val>.*), /$\{val}
通过RewritePath配置,可以针对路径进行重写
也可以通过default-filters配置默认filter作用于所有路由,比如:
spring:
cloud:
gateway:
default-filters:
- AddResponseHeader=X-Response-Test,111
自定义过滤器
通过使一个类继承AbstractNameValueGatewayFilterFactory,我们也可以自定义一个过滤器,然后应用于某些服务的过滤规则,
比如:
@Component
public class TokenGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
@Override
public GatewayFilter apply(NameValueConfig config) {
return (exchange, chain) -> chain.filter(exchange).then(Mono.fromRunnable(() -> {
ServerHttpResponse response = exchange.getResponse();
response.getHeaders().add(config.getName(), "testAAA");
}));
}
}
其中chain.filter(exchange).then()在这里必须使用.then来为response添加响应头。
| 方法 | 触发条件 | 用途 |
|---|---|---|
doOnSuccess | Mono 正常结束(不抛异常)时触发 | 监听“完成”但不适合做最终逻辑 |
then(...) | 串联后续逻辑,前一步成功后执行 | 推荐做副作用(加 header) |
doOnNext | Mono 有值发出 | Mono<Void> 不会触发 |
onErrorResume | 异常时触发 | 用于兜底逻辑 |
全局跨域
配置:
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowed-origin-patterns: '*'
allowed-headers: '*'
allowed-methods: '*'
许可协议:
CC BY-NC-SA 4.0