From 2c2f60cf58166f4e9510b4d9f03dfcf295e7f6b5 Mon Sep 17 00:00:00 2001 From: cdfive <31885791+cdfive@users.noreply.github.com> Date: Tue, 10 Mar 2020 23:02:07 +0800 Subject: [PATCH] Add "web-context-unify" config in Spring WebMVC adapter to support "chain" relation flow strategy (#1328) --- .../sentinel-spring-webmvc-adapter/README.md | 1 + .../webmvc/AbstractSentinelInterceptor.java | 13 ++++++++++++- .../spring/webmvc/SentinelWebInterceptor.java | 8 ++++++++ .../webmvc/config/SentinelWebMvcConfig.java | 18 ++++++++++++++++++ .../webmvc/config/InterceptorConfig.java | 1 + .../sentinel/adapter/servlet/CommonFilter.java | 2 +- .../webmvc/config/InterceptorConfig.java | 6 ++++++ 7 files changed, 47 insertions(+), 2 deletions(-) diff --git a/sentinel-adapter/sentinel-spring-webmvc-adapter/README.md b/sentinel-adapter/sentinel-spring-webmvc-adapter/README.md index 941daed4..cfbeb2da 100755 --- a/sentinel-adapter/sentinel-spring-webmvc-adapter/README.md +++ b/sentinel-adapter/sentinel-spring-webmvc-adapter/README.md @@ -97,6 +97,7 @@ config.setBlockExceptionHandler((request, response, e) -> { | urlCleaner | The `UrlCleaner` interface is designed for clean and unify the URL resource. | `UrlCleaner` | - | | requestAttributeName | Attribute key in request used by Sentinel (internal) | `String` | `$$sentinel_spring_web_entry_attr` | | httpMethodSpecify | Specify whether the URL resource name should contain the HTTP method prefix (e.g. `POST:`). | `boolean` | `false` | +| webContextUnify | Specify whether unify web context(i.e. use the default context name). | `boolean` | `true` | - `SentinelWebMvcTotalConfig` configuration: diff --git a/sentinel-adapter/sentinel-spring-webmvc-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/spring/webmvc/AbstractSentinelInterceptor.java b/sentinel-adapter/sentinel-spring-webmvc-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/spring/webmvc/AbstractSentinelInterceptor.java index e9f0a39e..d5c44d90 100644 --- a/sentinel-adapter/sentinel-spring-webmvc-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/spring/webmvc/AbstractSentinelInterceptor.java +++ b/sentinel-adapter/sentinel-spring-webmvc-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/spring/webmvc/AbstractSentinelInterceptor.java @@ -59,7 +59,8 @@ public abstract class AbstractSentinelInterceptor implements HandlerInterceptor if (StringUtil.isNotEmpty(resourceName)) { // Parse the request origin using registered origin parser. String origin = parseOrigin(request); - ContextUtil.enter(SENTINEL_SPRING_WEB_CONTEXT_NAME, origin); + String contextName = getContextName(request); + ContextUtil.enter(contextName, origin); Entry entry = SphU.entry(resourceName, ResourceTypeConstants.COMMON_WEB, EntryType.IN); setEntryInRequest(request, baseWebMvcConfig.getRequestAttributeName(), entry); @@ -79,6 +80,16 @@ public abstract class AbstractSentinelInterceptor implements HandlerInterceptor */ protected abstract String getResourceName(HttpServletRequest request); + /** + * Return the context name of the target web resource. + * + * @param request web request + * @return the context name of the target web resource. + */ + protected String getContextName(HttpServletRequest request) { + return SENTINEL_SPRING_WEB_CONTEXT_NAME; + } + @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { diff --git a/sentinel-adapter/sentinel-spring-webmvc-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/spring/webmvc/SentinelWebInterceptor.java b/sentinel-adapter/sentinel-spring-webmvc-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/spring/webmvc/SentinelWebInterceptor.java index b01b2c35..0c244d68 100644 --- a/sentinel-adapter/sentinel-spring-webmvc-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/spring/webmvc/SentinelWebInterceptor.java +++ b/sentinel-adapter/sentinel-spring-webmvc-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/spring/webmvc/SentinelWebInterceptor.java @@ -66,4 +66,12 @@ public class SentinelWebInterceptor extends AbstractSentinelInterceptor { return resourceName; } + @Override + protected String getContextName(HttpServletRequest request) { + if (config.isWebContextUnify()) { + return super.getContextName(request); + } + + return getResourceName(request); + } } diff --git a/sentinel-adapter/sentinel-spring-webmvc-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/spring/webmvc/config/SentinelWebMvcConfig.java b/sentinel-adapter/sentinel-spring-webmvc-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/spring/webmvc/config/SentinelWebMvcConfig.java index 29a2891c..c94ff8c2 100755 --- a/sentinel-adapter/sentinel-spring-webmvc-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/spring/webmvc/config/SentinelWebMvcConfig.java +++ b/sentinel-adapter/sentinel-spring-webmvc-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/spring/webmvc/config/SentinelWebMvcConfig.java @@ -29,11 +29,19 @@ public class SentinelWebMvcConfig extends BaseWebMvcConfig { * Specify the URL cleaner that unifies the URL resources. */ private UrlCleaner urlCleaner; + /** * Specify whether the URL resource name should contain the HTTP method prefix (e.g. {@code POST:}). */ private boolean httpMethodSpecify; + /** + * Specify whether unify web context(i.e. use the default context name), and is true by default. + * + * @since 1.7.2 + */ + private boolean webContextUnify = true; + public SentinelWebMvcConfig() { super(); setRequestAttributeName(DEFAULT_REQUEST_ATTRIBUTE_NAME); @@ -57,11 +65,21 @@ public class SentinelWebMvcConfig extends BaseWebMvcConfig { return this; } + public boolean isWebContextUnify() { + return webContextUnify; + } + + public SentinelWebMvcConfig setWebContextUnify(boolean webContextUnify) { + this.webContextUnify = webContextUnify; + return this; + } + @Override public String toString() { return "SentinelWebMvcConfig{" + "urlCleaner=" + urlCleaner + ", httpMethodSpecify=" + httpMethodSpecify + + ", webContextUnify=" + webContextUnify + ", requestAttributeName='" + requestAttributeName + '\'' + ", blockExceptionHandler=" + blockExceptionHandler + ", originParser=" + originParser + diff --git a/sentinel-adapter/sentinel-spring-webmvc-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/spring/webmvc/config/InterceptorConfig.java b/sentinel-adapter/sentinel-spring-webmvc-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/spring/webmvc/config/InterceptorConfig.java index 1ff24fd2..5b167a0c 100644 --- a/sentinel-adapter/sentinel-spring-webmvc-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/spring/webmvc/config/InterceptorConfig.java +++ b/sentinel-adapter/sentinel-spring-webmvc-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/spring/webmvc/config/InterceptorConfig.java @@ -66,6 +66,7 @@ public class InterceptorConfig implements WebMvcConfigurer { //Custom configuration if necessary config.setHttpMethodSpecify(false); + config.setWebContextUnify(true); config.setOriginParser(new RequestOriginParser() { @Override public String parseOrigin(HttpServletRequest request) { diff --git a/sentinel-adapter/sentinel-web-servlet/src/main/java/com/alibaba/csp/sentinel/adapter/servlet/CommonFilter.java b/sentinel-adapter/sentinel-web-servlet/src/main/java/com/alibaba/csp/sentinel/adapter/servlet/CommonFilter.java index e246e06c..f7bf3d61 100755 --- a/sentinel-adapter/sentinel-web-servlet/src/main/java/com/alibaba/csp/sentinel/adapter/servlet/CommonFilter.java +++ b/sentinel-adapter/sentinel-web-servlet/src/main/java/com/alibaba/csp/sentinel/adapter/servlet/CommonFilter.java @@ -54,7 +54,7 @@ public class CommonFilter implements Filter { */ public static final String HTTP_METHOD_SPECIFY = "HTTP_METHOD_SPECIFY"; /** - * If enabled, use the URL path as the context name, or else use the default + * If enabled, use the default context name, or else use the URL path as the context name, * {@link WebServletConfig#WEB_SERVLET_CONTEXT_NAME}. Please pay attention to the number of context (EntranceNode), * which may affect the memory footprint. * diff --git a/sentinel-demo/sentinel-demo-spring-webmvc/src/main/java/com/alibaba/csp/sentinel/demo/spring/webmvc/config/InterceptorConfig.java b/sentinel-demo/sentinel-demo-spring-webmvc/src/main/java/com/alibaba/csp/sentinel/demo/spring/webmvc/config/InterceptorConfig.java index 58509df2..c90f5165 100644 --- a/sentinel-demo/sentinel-demo-spring-webmvc/src/main/java/com/alibaba/csp/sentinel/demo/spring/webmvc/config/InterceptorConfig.java +++ b/sentinel-demo/sentinel-demo-spring-webmvc/src/main/java/com/alibaba/csp/sentinel/demo/spring/webmvc/config/InterceptorConfig.java @@ -53,6 +53,12 @@ public class InterceptorConfig implements WebMvcConfigurer { // Custom configuration if necessary config.setHttpMethodSpecify(true); + // By default web context is true, means that unify web context(i.e. use the default context name), + // in most scenarios that's enough, and it could reduce the memory footprint. + // If set it to false, entrance contexts will be separated by different URLs, + // which is useful to support "chain" relation flow strategy. + // We can change it and view different result in `Resource Chain` menu of dashboard. + config.setWebContextUnify(true); config.setOriginParser(request -> request.getHeader("S-user")); // Add sentinel interceptor