|
|
@@ -1,23 +1,19 @@ |
|
|
|
# Sentinel Zuul Adapter |
|
|
|
|
|
|
|
Zuul does not provide rateLimit function, If use default `SentinelRibbonFilter` route filter. it wrapped by Hystrix Command. so only provide Service level |
|
|
|
circuit protect. |
|
|
|
Sentinel Zuul Adapter provides **ServiceId level** and **API Path level** flow control for Zuul gateway service. |
|
|
|
|
|
|
|
Sentinel can provide `ServiceId` level and `API Path` level flow control for zuul gateway service. |
|
|
|
|
|
|
|
*Note*: this project is for zuul 1. |
|
|
|
> *Note*: this adapter only support Zuul 1.x. |
|
|
|
|
|
|
|
## How to use |
|
|
|
|
|
|
|
1. Add maven dependency |
|
|
|
1. Add Maven dependency to your `pom.xml`: |
|
|
|
|
|
|
|
```xml |
|
|
|
<dependency> |
|
|
|
<groupId>com.alibaba.csp</groupId> |
|
|
|
<artifactId>sentinel-zuul-adapter</artifactId> |
|
|
|
<version>x.y.z</version> |
|
|
|
</dependency> |
|
|
|
|
|
|
|
<dependency> |
|
|
|
<groupId>com.alibaba.csp</groupId> |
|
|
|
<artifactId>sentinel-zuul-adapter</artifactId> |
|
|
|
<version>x.y.z</version> |
|
|
|
</dependency> |
|
|
|
``` |
|
|
|
|
|
|
|
2. Register filters |
|
|
@@ -25,12 +21,12 @@ Sentinel can provide `ServiceId` level and `API Path` level flow control for zuu |
|
|
|
```java |
|
|
|
// get registry |
|
|
|
final FilterRegistry r = FilterRegistry.instance(); |
|
|
|
// this is property config. set filter ennable |
|
|
|
// this is property config. set filter enable |
|
|
|
SentinelZuulProperties properties = new SentinelZuulProperties(); |
|
|
|
properties.setEnabled(true); |
|
|
|
// set url cleaner, here use default |
|
|
|
// set url cleaner, here use default |
|
|
|
DefaultUrlCleaner defaultUrlCleaner = new DefaultUrlCleaner(); |
|
|
|
// set origin parser. here use default |
|
|
|
// set origin parser. here use default |
|
|
|
DefaultRequestOriginParser defaultRequestOriginParser = new DefaultRequestOriginParser(); |
|
|
|
|
|
|
|
// register filters. you must register all three filters. |
|
|
@@ -44,22 +40,19 @@ r.put("sentinelErrorFilter", errorFilter); |
|
|
|
|
|
|
|
## How it works |
|
|
|
|
|
|
|
As Zuul run as per thread per connection block model, we add filters around `route Filter` to trace sentinel statistics. |
|
|
|
|
|
|
|
- `SentinelPreFilter`: Get an entry of resource,the first order is **ServiceId**(the key in RequestContext is `serviceId`, this can set in own custom filter), then **API Path**. |
|
|
|
- `SentinelPostFilter`: When success response,exit entry. |
|
|
|
- `SentinelPreFilter`: When get an `Exception`, trace the exception and exit context. |
|
|
|
|
|
|
|
|
|
|
|
the order of Filter can be changed in property: |
|
|
|
As Zuul run as per thread per connection block model, we add filters around `route Filter` to trace sentinel statistics. |
|
|
|
|
|
|
|
- `SentinelPreFilter`: Get an entry of resource, the first order is **ServiceId** (the key in RequestContext is `serviceId`, this can set in own custom filter), then **API Path**. |
|
|
|
- `SentinelPostFilter`: When success response, exit entry. |
|
|
|
- `SentinelPreFilter`: When an `Exception` caught, trace the exception and exit context. |
|
|
|
|
|
|
|
<img width="792" src="https://user-images.githubusercontent.com/9305625/47277113-6b5da780-d5ef-11e8-8a0a-93a6b09b0887.png"> |
|
|
|
|
|
|
|
Filters create structure like: |
|
|
|
The order of filters can be changed in property. |
|
|
|
|
|
|
|
The invocation chain resembles this: |
|
|
|
|
|
|
|
```bash |
|
|
|
|
|
|
|
EntranceNode: machine-root(t:3 pq:0 bq:0 tq:0 rt:0 prq:0 1mp:0 1mb:0 1mt:0) |
|
|
|
-EntranceNode: coke(t:2 pq:0 bq:0 tq:0 rt:0 prq:0 1mp:0 1mb:0 1mt:0) |
|
|
|
--coke(t:2 pq:0 bq:0 tq:0 rt:0 prq:0 1mp:0 1mb:0 1mt:0) |
|
|
@@ -68,38 +61,33 @@ EntranceNode: machine-root(t:3 pq:0 bq:0 tq:0 rt:0 prq:0 1mp:0 1mb:0 1mt:0) |
|
|
|
-EntranceNode: book(t:1 pq:0 bq:0 tq:0 rt:0 prq:0 1mp:0 1mb:0 1mt:0) |
|
|
|
--book(t:1 pq:0 bq:0 tq:0 rt:0 prq:0 1mp:0 1mb:0 1mt:0) |
|
|
|
---/book/coke(t:0 pq:0 bq:0 tq:0 rt:0 prq:0 1mp:0 1mb:0 1mt:0) |
|
|
|
|
|
|
|
``` |
|
|
|
|
|
|
|
`book` and `coke` are serviceId. |
|
|
|
|
|
|
|
`---/book/coke` is api path, the real uri is `/coke`. |
|
|
|
|
|
|
|
- `book` and `coke` are serviceId. |
|
|
|
- `/book/coke` is api path, the real API path is `/coke`. |
|
|
|
|
|
|
|
## Integration with Sentinel DashBord |
|
|
|
## Integration with Sentinel Dashboard |
|
|
|
|
|
|
|
1. Start [Sentinel DashBord](https://github.com/alibaba/Sentinel/wiki/%E6%8E%A7%E5%88%B6%E5%8F%B0). |
|
|
|
|
|
|
|
2. Sentinel has full rule config features. see [Dynamic-Rule-Configuration](https://github.com/alibaba/Sentinel/wiki/Dynamic-Rule-Configuration) |
|
|
|
1. Start [Sentinel Dashboard](https://github.com/alibaba/Sentinel/wiki/Dashboard). |
|
|
|
2. You can configure the rules in Sentinel dashboard or via dynamic rule configuration. |
|
|
|
|
|
|
|
## Fallbacks |
|
|
|
|
|
|
|
Implements `SentinelFallbackProvider` to define your own Fallback Provider when Sentinel Block Exception throwing. the default |
|
|
|
Fallback Provider is `DefaultBlockFallbackProvider`. |
|
|
|
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 `ServiveId + URI PATH`, example `/book/coke`, first `book` is serviceId, `/coke` is URI PATH. so that both |
|
|
|
can be needed. |
|
|
|
By default fallback route is `ServiveId + URI PATH`, example `/book/coke`, first `book` is serviceId, `/coke` is URI PATH, so that both can be needed. |
|
|
|
|
|
|
|
Here is an example: |
|
|
|
|
|
|
|
```java |
|
|
|
|
|
|
|
// custom provider |
|
|
|
// custom provider |
|
|
|
public class MyBlockFallbackProvider implements ZuulBlockFallbackProvider { |
|
|
|
|
|
|
|
private Logger logger = LoggerFactory.getLogger(DefaultBlockFallbackProvider.class); |
|
|
|
|
|
|
|
// you can define root as service level |
|
|
|
|
|
|
|
// you can define root as service level |
|
|
|
@Override |
|
|
|
public String getRoute() { |
|
|
|
return "/coke/coke"; |
|
|
@@ -115,16 +103,14 @@ public class MyBlockFallbackProvider implements ZuulBlockFallbackProvider { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// register fallback |
|
|
|
ZuulBlockFallbackManager.registerProvider(new MyBlockFallbackProvider()); |
|
|
|
|
|
|
|
``` |
|
|
|
|
|
|
|
Default block response |
|
|
|
Default block response: |
|
|
|
|
|
|
|
```json |
|
|
|
|
|
|
|
{ |
|
|
|
"code":429, |
|
|
|
"message":"Sentinel block exception", |
|
|
@@ -132,17 +118,15 @@ Default block response |
|
|
|
} |
|
|
|
``` |
|
|
|
|
|
|
|
## Origin parser |
|
|
|
## Request origin parser |
|
|
|
|
|
|
|
自定义解析URL |
|
|
|
You can register customized request origin parser like this: |
|
|
|
|
|
|
|
```java |
|
|
|
|
|
|
|
public class DefaultRequestOriginParser implements RequestOriginParser { |
|
|
|
public class MyRequestOriginParser implements RequestOriginParser { |
|
|
|
@Override |
|
|
|
public String parseOrigin(HttpServletRequest request) { |
|
|
|
return ""; |
|
|
|
return request.getRemoteAddr(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
``` |
|
|
|
``` |