tao.zhang 73188b46b7 Fix the bug that the Zuul adapter does not exit the entry with parameters (#1148) | 5 år sedan | |
---|---|---|
.. | ||
src | 5 år sedan | |
README.md | 5 år sedan | |
pom.xml | 5 år sedan |
Sentinel Zuul Adapter provides route level and customized API level flow control for Zuul API Gateway.
Note: this adapter only support Zuul 1.x.
pom.xml
:<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-zuul-adapter</artifactId>
<version>x.y.z</version>
</dependency>
For Spring Cloud Zuul users, we only need to inject the three filters in Spring configuration class like this:
@Configuration
public class ZuulConfig {
@Bean
public ZuulFilter sentinelZuulPreFilter() {
// We can provider the filter order here.
return new SentinelZuulPreFilter(10000);
}
@Bean
public ZuulFilter sentinelZuulPostFilter() {
return new SentinelZuulPostFilter(1000);
}
@Bean
public ZuulFilter sentinelZuulErrorFilter() {
return new SentinelZuulErrorFilter(-1);
}
}
For original Zuul users:
// Get filter registry
final FilterRegistry r = FilterRegistry.instance();
// We need to register all three filters.
SentinelZuulPreFilter sentinelPreFilter = new SentinelZuulPreFilter();
r.put("sentinelZuulPreFilter", sentinelPreFilter);
SentinelZuulPostFilter postFilter = new SentinelZuulPostFilter();
r.put("sentinelZuulPostFilter", postFilter);
SentinelZuulErrorFilter errorFilter = new SentinelZuulErrorFilter();
r.put("sentinelZuulErrorFilter", errorFilter);
As Zuul run as per thread per connection block model, we add filters around route filter to trace Sentinel statistics.
SentinelZuulPreFilter
: This pre-filter will regard all proxy ID (proxy
in RequestContext
) and all customized API as resources. When a BlockException
caught, the filter will try to find a fallback to execute.SentinelZuulPostFilter
: When the response has no exception caught, the post filter will complete the entries.SentinelZuulPreFilter
: When an exception is caught, the filter will trace the exception and complete the entries.The order of filters can be changed via the constructor.
The invocation chain resembles this:
-EntranceNode: sentinel_gateway_context$$route$$another-route-b(t:0 pq:0.0 bq:0.0 tq:0.0 rt:0.0 prq:0.0 1mp:8 1mb:1 1mt:9)
--another-route-b(t:0 pq:0.0 bq:0.0 tq:0.0 rt:0.0 prq:0.0 1mp:4 1mb:1 1mt:5)
--another_customized_api(t:0 pq:0.0 bq:0.0 tq:0.0 rt:0.0 prq:0.0 1mp:4 1mb:0 1mt:4)
-EntranceNode: sentinel_gateway_context$$route$$my-route-1(t:0 pq:0.0 bq:0.0 tq:0.0 rt:0.0 prq:0.0 1mp:6 1mb:0 1mt:6)
--my-route-1(t:0 pq:0.0 bq:0.0 tq:0.0 rt:0.0 prq:0.0 1mp:2 1mb:0 1mt:2)
--some_customized_api(t:0 pq:0.0 bq:0.0 tq:0.0 rt:0.0 prq:0.0 1mp:2 1mb:0 1mt:2)
You can implement SentinelFallbackProvider
to define your own fallback provider when Sentinel BlockException
is thrown.
The default fallback provider is DefaultBlockFallbackProvider
.
By default fallback route is proxy ID (or customized API name).
Here is an example:
// custom provider
public class MyBlockFallbackProvider implements ZuulBlockFallbackProvider {
private Logger logger = LoggerFactory.getLogger(DefaultBlockFallbackProvider.class);
// you can define root as service level
@Override
public String getRoute() {
return "my-route";
}
@Override
public BlockResponse fallbackResponse(String route, Throwable cause) {
RecordLog.info(String.format("[Sentinel DefaultBlockFallbackProvider] Run fallback route: %s", route));
if (cause instanceof BlockException) {
return new BlockResponse(429, "Sentinel block exception", route);
} else {
return new BlockResponse(500, "System Error", route);
}
}
}
// register fallback
ZuulBlockFallbackManager.registerProvider(new MyBlockFallbackProvider());
Default block response:
{
"code":429,
"message":"Sentinel block exception",
"route":"/"
}
You can register customized request origin parser like this:
public class MyRequestOriginParser implements RequestOriginParser {
@Override
public String parseOrigin(HttpServletRequest request) {
return request.getRemoteAddr();
}
}