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 4.0