Use the unified context name instead in Web Servlet filter and code improvement (#944)
Signed-off-by: Eric Zhao <sczyh16@gmail.com>
This commit is contained in:
parent
103fa307e5
commit
37e78e511d
|
|
@ -1,6 +1,7 @@
|
||||||
# Sentinel Web Servlet Filter
|
# Sentinel Web Servlet Filter
|
||||||
|
|
||||||
Sentinel provides Servlet filter integration to enable flow control for web requests. Add the following dependency in `pom.xml` (if you are using Maven):
|
Sentinel provides Servlet filter integration to enable flow control for web requests.
|
||||||
|
Add the following dependency in `pom.xml` (if you are using Maven):
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
@ -10,7 +11,7 @@ Sentinel provides Servlet filter integration to enable flow control for web requ
|
||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
|
|
||||||
To use the filter, you can simply configure your `web.xml` with:
|
To activate the filter, you can simply configure your `web.xml` with:
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<filter>
|
<filter>
|
||||||
|
|
@ -34,8 +35,9 @@ public class FilterConfig {
|
||||||
public FilterRegistrationBean sentinelFilterRegistration() {
|
public FilterRegistrationBean sentinelFilterRegistration() {
|
||||||
FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();
|
FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();
|
||||||
registration.setFilter(new CommonFilter());
|
registration.setFilter(new CommonFilter());
|
||||||
|
// Set the matching URL pattern for the filter.
|
||||||
registration.addUrlPatterns("/*");
|
registration.addUrlPatterns("/*");
|
||||||
registration.setName("sentinelFilter");
|
registration.setName("sentinelCommonFilter");
|
||||||
registration.setOrder(1);
|
registration.setOrder(1);
|
||||||
|
|
||||||
return registration;
|
return registration;
|
||||||
|
|
@ -43,7 +45,7 @@ public class FilterConfig {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
When a request is blocked, Sentinel servlet filter will give a default page indicating the request blocked.
|
When a request is blocked, Sentinel servlet filter will display a default page indicating the request is rejected.
|
||||||
If customized block page is set (via `WebServletConfig.setBlockPage(blockPage)` method),
|
If customized block page is set (via `WebServletConfig.setBlockPage(blockPage)` method),
|
||||||
the filter will redirect the request to provided URL. You can also implement your own
|
the filter will redirect the request to provided URL. You can also implement your own
|
||||||
block handler (the `UrlBlockHandler` interface) and register to `WebCallbackManager`.
|
block handler (the `UrlBlockHandler` interface) and register to `WebCallbackManager`.
|
||||||
|
|
@ -51,8 +53,10 @@ block handler (the `UrlBlockHandler` interface) and register to `WebCallbackMana
|
||||||
The `UrlCleaner` interface is designed for clean and unify the URL resource.
|
The `UrlCleaner` interface is designed for clean and unify the URL resource.
|
||||||
For REST APIs, you have to clean the URL resource (e.g. `/foo/1` and `/foo/2` -> `/foo/:id`), or
|
For REST APIs, you have to clean the URL resource (e.g. `/foo/1` and `/foo/2` -> `/foo/:id`), or
|
||||||
the amount of context and resources will exceed the threshold.
|
the amount of context and resources will exceed the threshold.
|
||||||
The `UrlCleaner` interface can also exclude unused URLs(e.g. `/exclude/1` -> `/exclude/:id` -> `""`).
|
|
||||||
The URLs will be filtered and not be resource in this way.
|
If you need to exclude some URLs (that should not be recorded as Sentinel resources), you could also
|
||||||
|
leverage the `UrlCleaner` interface. You may unify the unwanted URLs to the empty string `""`,
|
||||||
|
then the URLs will be excluded (since Sentinel 1.6.3).
|
||||||
|
|
||||||
`RequestOriginParser` interface is useful for extracting request origin (e.g. IP or appName from HTTP Header)
|
`RequestOriginParser` interface is useful for extracting request origin (e.g. IP or appName from HTTP Header)
|
||||||
from HTTP request. You can implement your own `RequestOriginParser` and register to `WebCallbackManager`.
|
from HTTP request. You can implement your own `RequestOriginParser` and register to `WebCallbackManager`.
|
||||||
|
|
@ -33,6 +33,7 @@ import com.alibaba.csp.sentinel.Tracer;
|
||||||
import com.alibaba.csp.sentinel.adapter.servlet.callback.RequestOriginParser;
|
import com.alibaba.csp.sentinel.adapter.servlet.callback.RequestOriginParser;
|
||||||
import com.alibaba.csp.sentinel.adapter.servlet.callback.UrlCleaner;
|
import com.alibaba.csp.sentinel.adapter.servlet.callback.UrlCleaner;
|
||||||
import com.alibaba.csp.sentinel.adapter.servlet.callback.WebCallbackManager;
|
import com.alibaba.csp.sentinel.adapter.servlet.callback.WebCallbackManager;
|
||||||
|
import com.alibaba.csp.sentinel.adapter.servlet.config.WebServletConfig;
|
||||||
import com.alibaba.csp.sentinel.adapter.servlet.util.FilterUtil;
|
import com.alibaba.csp.sentinel.adapter.servlet.util.FilterUtil;
|
||||||
import com.alibaba.csp.sentinel.context.ContextUtil;
|
import com.alibaba.csp.sentinel.context.ContextUtil;
|
||||||
import com.alibaba.csp.sentinel.slots.block.BlockException;
|
import com.alibaba.csp.sentinel.slots.block.BlockException;
|
||||||
|
|
@ -59,9 +60,8 @@ public class CommonFilter implements Filter {
|
||||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||||
throws IOException, ServletException {
|
throws IOException, ServletException {
|
||||||
HttpServletRequest sRequest = (HttpServletRequest) request;
|
HttpServletRequest sRequest = (HttpServletRequest) request;
|
||||||
Entry entry = null;
|
Entry urlEntry = null;
|
||||||
|
Entry httpMethodUrlEntry = null;
|
||||||
Entry methodEntry = null;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String target = FilterUtil.filterTarget(sRequest);
|
String target = FilterUtil.filterTarget(sRequest);
|
||||||
|
|
@ -78,11 +78,11 @@ public class CommonFilter implements Filter {
|
||||||
if (!StringUtil.isEmpty(target)) {
|
if (!StringUtil.isEmpty(target)) {
|
||||||
// Parse the request origin using registered origin parser.
|
// Parse the request origin using registered origin parser.
|
||||||
String origin = parseOrigin(sRequest);
|
String origin = parseOrigin(sRequest);
|
||||||
ContextUtil.enter(target, origin);
|
ContextUtil.enter(WebServletConfig.WEB_SERVLET_CONTEXT_NAME, origin);
|
||||||
entry = SphU.entry(target, EntryType.IN);
|
urlEntry = SphU.entry(target, EntryType.IN);
|
||||||
// Add method specification if necessary
|
// Add method specification if necessary
|
||||||
if (httpMethodSpecify) {
|
if (httpMethodSpecify) {
|
||||||
methodEntry = SphU.entry(sRequest.getMethod().toUpperCase() + COLON + target,
|
httpMethodUrlEntry = SphU.entry(sRequest.getMethod().toUpperCase() + COLON + target,
|
||||||
EntryType.IN);
|
EntryType.IN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -91,21 +91,16 @@ public class CommonFilter implements Filter {
|
||||||
HttpServletResponse sResponse = (HttpServletResponse) response;
|
HttpServletResponse sResponse = (HttpServletResponse) response;
|
||||||
// Return the block page, or redirect to another URL.
|
// Return the block page, or redirect to another URL.
|
||||||
WebCallbackManager.getUrlBlockHandler().blocked(sRequest, sResponse, e);
|
WebCallbackManager.getUrlBlockHandler().blocked(sRequest, sResponse, e);
|
||||||
} catch (IOException e2) {
|
} catch (IOException | ServletException | RuntimeException e2) {
|
||||||
Tracer.trace(e2);
|
Tracer.traceEntry(e2, urlEntry);
|
||||||
|
Tracer.traceEntry(e2, httpMethodUrlEntry);
|
||||||
throw e2;
|
throw e2;
|
||||||
} catch (ServletException e3) {
|
|
||||||
Tracer.trace(e3);
|
|
||||||
throw e3;
|
|
||||||
} catch (RuntimeException e4) {
|
|
||||||
Tracer.trace(e4);
|
|
||||||
throw e4;
|
|
||||||
} finally {
|
} finally {
|
||||||
if (methodEntry != null) {
|
if (httpMethodUrlEntry != null) {
|
||||||
methodEntry.exit();
|
httpMethodUrlEntry.exit();
|
||||||
}
|
}
|
||||||
if (entry != null) {
|
if (urlEntry != null) {
|
||||||
entry.exit();
|
urlEntry.exit();
|
||||||
}
|
}
|
||||||
ContextUtil.exit();
|
ContextUtil.exit();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ import com.alibaba.csp.sentinel.Entry;
|
||||||
import com.alibaba.csp.sentinel.SphU;
|
import com.alibaba.csp.sentinel.SphU;
|
||||||
import com.alibaba.csp.sentinel.Tracer;
|
import com.alibaba.csp.sentinel.Tracer;
|
||||||
import com.alibaba.csp.sentinel.adapter.servlet.callback.WebCallbackManager;
|
import com.alibaba.csp.sentinel.adapter.servlet.callback.WebCallbackManager;
|
||||||
|
import com.alibaba.csp.sentinel.adapter.servlet.config.WebServletConfig;
|
||||||
import com.alibaba.csp.sentinel.adapter.servlet.util.FilterUtil;
|
import com.alibaba.csp.sentinel.adapter.servlet.util.FilterUtil;
|
||||||
import com.alibaba.csp.sentinel.context.ContextUtil;
|
import com.alibaba.csp.sentinel.context.ContextUtil;
|
||||||
import com.alibaba.csp.sentinel.slots.block.BlockException;
|
import com.alibaba.csp.sentinel.slots.block.BlockException;
|
||||||
|
|
@ -52,26 +53,18 @@ public class CommonTotalFilter implements Filter {
|
||||||
public void doFilter(ServletRequest request, ServletResponse response,
|
public void doFilter(ServletRequest request, ServletResponse response,
|
||||||
FilterChain chain) throws IOException, ServletException {
|
FilterChain chain) throws IOException, ServletException {
|
||||||
HttpServletRequest sRequest = (HttpServletRequest)request;
|
HttpServletRequest sRequest = (HttpServletRequest)request;
|
||||||
String target = FilterUtil.filterTarget(sRequest);
|
|
||||||
target = WebCallbackManager.getUrlCleaner().clean(target);
|
|
||||||
|
|
||||||
Entry entry = null;
|
Entry entry = null;
|
||||||
try {
|
try {
|
||||||
ContextUtil.enter(target);
|
ContextUtil.enter(WebServletConfig.WEB_SERVLET_CONTEXT_NAME);
|
||||||
entry = SphU.entry(TOTAL_URL_REQUEST);
|
entry = SphU.entry(TOTAL_URL_REQUEST);
|
||||||
chain.doFilter(request, response);
|
chain.doFilter(request, response);
|
||||||
} catch (BlockException e) {
|
} catch (BlockException e) {
|
||||||
HttpServletResponse sResponse = (HttpServletResponse)response;
|
HttpServletResponse sResponse = (HttpServletResponse)response;
|
||||||
WebCallbackManager.getUrlBlockHandler().blocked(sRequest, sResponse, e);
|
WebCallbackManager.getUrlBlockHandler().blocked(sRequest, sResponse, e);
|
||||||
} catch (IOException e2) {
|
} catch (IOException | ServletException | RuntimeException e2) {
|
||||||
Tracer.trace(e2);
|
Tracer.trace(e2);
|
||||||
throw e2;
|
throw e2;
|
||||||
} catch (ServletException e3) {
|
|
||||||
Tracer.trace(e3);
|
|
||||||
throw e3;
|
|
||||||
} catch (RuntimeException e4) {
|
|
||||||
Tracer.trace(e4);
|
|
||||||
throw e4;
|
|
||||||
} finally {
|
} finally {
|
||||||
if (entry != null) {
|
if (entry != null) {
|
||||||
entry.exit();
|
entry.exit();
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@ import com.alibaba.csp.sentinel.config.SentinelConfig;
|
||||||
*/
|
*/
|
||||||
public class WebServletConfig {
|
public class WebServletConfig {
|
||||||
|
|
||||||
|
public static final String WEB_SERVLET_CONTEXT_NAME = "sentinel_web_servlet_context";
|
||||||
|
|
||||||
public static final String BLOCK_PAGE = "csp.sentinel.web.servlet.block.page";
|
public static final String BLOCK_PAGE = "csp.sentinel.web.servlet.block.page";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue