全局过滤器GlobalFilte
接口与 GatewayFilter
具有相同的签名,这些特定的过滤器有条件的应用到所有的路由上。
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.0.RC1/reference/html/#global-filters
组合使用GlobalFilter和GatewayFilter
当请求进来的时候,过滤器Web处理器将会将所有的GlobalFilter
实例和所有特定的GatewayFilter
路由实例添加到过滤器filter链中,该组合的过滤器按org.springframework.core.Ordered
接口排序,通过实现getOrder()
方法来设置。
由于Spring Cloud Gateway 区分了过滤器逻辑执行器的”前”阶段和”后”阶段,因此优先级最高的过滤器在pre
阶段中处于第一个,而在post
阶段处于最后一个。
CustomGlobalFilter.java
1 2 3 4 5 6 7 8 9 10 11 12
| public class CustomGlobalFilter implements GlobalFilter,Ordered {
@Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { return chain.filter(exchange); }
@Override public int getOrder() { return 0; } }
|
注意:数值越小,越靠前执行。
LoadBalancerClient
将LoadBalancerClientFilter
在交换属性查找一个URI ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
。如果url有一个lb
方案(即lb://myservice
),它将使用Spring Cloud LoadBalancerClient
将名称(myservice
在前面的示例中)解析为实际的主机和端口,并在同一属性中替换URI。未经修改的原始url将附加到ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR
属性中的列表。过滤器还将在ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR
属性中查找是否相等lb
,然后应用相同的规则
application.yaml
1 2 3 4 5 6 7 8
| spring: cloud: gateway: routes: - id: myRoute uri: lb://service predicates: - Path=/service/**
|
上面的介绍难以理解,其实通过代码可以看出,就是使用lb
来指定是否使用ribbon负载均衡。可以发现,这里Gateway也是使用ribbon来实现负载均衡的。
默认情况下,当一个服务示例不能被LoadBalancer
发现,将会返回503
, 我们可以配置spring.cloud.gateway.loadbalancer.use404 = false
来使得Gateway返回404
.
我们建议使用ReactiveLoadBalancerClientFilter
。您可以通过设置spring.cloud.loadbalancer.ribbon.enabled
的值为false
来使用ReactiveLoadBalancerClientFilter
.
ReactiveLoadBalancerClientFilter
如上,见识使用这个,只需要将spring.cloud.loadbalancer.ribbon.enabled
设置为false就可以了。
Sentinel 整合Gateway
1 2 3 4 5
| <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId> <version>2.1.0.RELEASE</version> </dependency>
|
配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
|
@Configuration public class GatewayConfiguration {
private final List<ViewResolver> viewResolvers; private final ServerCodecConfigurer serverCodecConfigurer;
public GatewayConfiguration(ObjectProvider<List<ViewResolver>> viewResolversProvider, ServerCodecConfigurer serverCodecConfigurer) { this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList); this.serverCodecConfigurer = serverCodecConfigurer; }
private void initCustomizedApis() { Set<ApiDefinition> definitions = new HashSet<>();
ApiDefinition api1 = new ApiDefinition("some_customized_api") .setPredicateItems(new HashSet<ApiPredicateItem>() {{ add(new ApiPathPredicateItem().setPattern("/ahas")); add(new ApiPathPredicateItem().setPattern("/product/**") .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX)); }});
ApiDefinition api2 = new ApiDefinition("another_customized_api") .setPredicateItems(new HashSet<ApiPredicateItem>() {{ add(new ApiPathPredicateItem().setPattern("/**") .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX)); }}); definitions.add(api1); definitions.add(api2); GatewayApiDefinitionManager.loadApiDefinitions(definitions); }
private void initGatewayRules() { Set<GatewayFlowRule> rules = new HashSet<>(); rules.add(new GatewayFlowRule("aliyun_route") .setCount(10) .setIntervalSec(1) );
rules.add(new GatewayFlowRule("aliyun_route") .setCount(2) .setIntervalSec(2) .setBurst(2) .setParamItem(new GatewayParamFlowItem() .setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_CLIENT_IP) ) ); rules.add(new GatewayFlowRule("httpbin_route") .setCount(10) .setIntervalSec(1) .setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER) .setMaxQueueingTimeoutMs(600) .setParamItem(new GatewayParamFlowItem() .setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_HEADER) .setFieldName("X-Sentinel-Flag") ) ); rules.add(new GatewayFlowRule("httpbin_route") .setCount(1) .setIntervalSec(1) .setParamItem(new GatewayParamFlowItem() .setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_URL_PARAM) .setFieldName("pa") ) ); rules.add(new GatewayFlowRule("httpbin_route") .setCount(2) .setIntervalSec(30) .setParamItem(new GatewayParamFlowItem() .setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_URL_PARAM) .setFieldName("type") .setPattern("warn") .setMatchStrategy(SentinelGatewayConstants.PARAM_MATCH_STRATEGY_CONTAINS) ) );
rules.add(new GatewayFlowRule("some_customized_api") .setResourceMode(SentinelGatewayConstants.RESOURCE_MODE_CUSTOM_API_NAME) .setCount(5) .setIntervalSec(1) .setParamItem(new GatewayParamFlowItem() .setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_URL_PARAM) .setFieldName("pn") ) ); GatewayRuleManager.loadRules(rules); } }
|