Skip to content

Spring WebFlux Adapter Support "BEST_MATCHING_PATTERN_ATTRIBUTE"#2628

Open
icodening wants to merge 4 commits intoalibaba:masterfrom
icodening:webflux-bestmatching
Open

Spring WebFlux Adapter Support "BEST_MATCHING_PATTERN_ATTRIBUTE"#2628
icodening wants to merge 4 commits intoalibaba:masterfrom
icodening:webflux-bestmatching

Conversation

@icodening
Copy link
Copy Markdown
Contributor

@icodening icodening commented Mar 29, 2022

Describe what this PR does / why we need it

Spring WebFlux下使用Sentinel,支持将Path参数的路径视为同一资源。
如在 /users/{id} 下,/users/1、/users/2将被视为同一个资源 "/users/{id}"

Does this pull request fix one issue?

Fixes #2627

Describe how you did it

在SentinelWebFluxFilter中获取path动作之前加入获取"BEST_MATCHING_PATTERN_ATTRIBUTE"的埋点,如果埋点获取的结果为空,则使用默认的获取资源名逻辑
image

Describe how to verify it

需要使用新的方式装配 SentinelWebFluxFilter,方式如下

/**
 * best matching pattern extractor for RouterFunctionMapping
 */
@Bean
public HandlerMappingBestMatchingPatternExtractor routerFunctionBestMatchingPatternExtractor() {
    return new RouterFunctionMappingBestMatchingPatternExtractor();
}

/**
 * best matching pattern extractor for RequestMappingHandlerMapping
 */
@Bean
public HandlerMappingBestMatchingPatternExtractor requestMappingHandlerMappingBestMatchingExtractor() {
    return new RequestMappingHandlerMappingBestMatchingPatternExtractor();
}

@Bean
public SentinelWebFluxFilter sentinelWebFluxFilter(List<HandlerMapping> handlerMappings,
                                                   List<HandlerMappingBestMatchingPatternExtractor> handlerMappingBestMatchingExtractors) {
    return new SentinelWebFluxFilter(new DefaultBestMatchingPatternExtractor(handlerMappings, handlerMappingBestMatchingExtractors));
}

Special notes for reviews

下图为大致流程图可帮助理解
image

其中,HandlerMappingBestMatchingPatternExtractor接口有两个默认实现分别为RequestMappingHandlerMappingBestMatchingPatternExtractor, RouterFunctionMappingBestMatchingPatternExtractor. 两个提取器分别处理RequestMappingHandlerMapping与RouterFunctionMapping

@sczyh30 sczyh30 added kind/enhancement Category issues or prs related to enhancement. to-review To review area/integrations Issues or PRs related to integrations with open-source components labels Mar 30, 2022
@sczyh30 sczyh30 self-requested a review March 30, 2022 02:01
Copy link
Copy Markdown
Member

@sczyh30 sczyh30 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add test cases for this feature?

@icodening
Copy link
Copy Markdown
Contributor Author

Could you please add test cases for this feature?

OK,I will add test case soon

@icodening icodening requested a review from sczyh30 March 30, 2022 15:12
@icodening
Copy link
Copy Markdown
Contributor Author

Could you please add test cases for this feature?

I have added test code, please review

@sczyh30 sczyh30 requested review from brotherlu-xcq and cdfive April 2, 2022 01:51
@Hodor125
Copy link
Copy Markdown

Why is this feature not merged, is there any problem?

@wuwen5
Copy link
Copy Markdown
Contributor

wuwen5 commented Dec 8, 2022

能否不修改SentinelWebFluxFilter,而通过WebFluxCallbackManager.setUrlCleaner 来插入实现。

我们是否可以类似这样

BiFunction<ServerWebExchange, String, String>  cleaner = (exchange, originUrl)-> {

          for (HandlerMapping handlerMapping : handlerMappings) {
              for (HandlerMappingBestMatchingPatternExtractor handlerMappingBestMatchingPatternExtractor : handlerMappingBestMatchingPatternExtractors) {
                  if (!handlerMappingBestMatchingPatternExtractor.supportExtract(handlerMapping)) {
                      continue;
                  }
                  String bestMatchingPath = handlerMappingBestMatchingPatternExtractor.extract(handlerMapping, exchange);
                  if (bestMatchingPath != null) {
                      return bestMatchingPath;
                  }
              }
          }
          
          PathPattern pathPattern = exchange.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
          if (pathPattern != null && pathPattern.matches(exchange.getRequest().getPath().pathWithinApplication())) {
              return pathPattern.getPatternString();
          }
          return originUrl;
      };

      WebFluxCallbackManager.setUrlCleaner(cleaner);

return this.exchange.getRequest();
}

public ServerWebExchange exchange() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里是否缺少了一个 @Override?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/integrations Issues or PRs related to integrations with open-source components kind/enhancement Category issues or prs related to enhancement. to-review To review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Spring WebFlux下相同Pattern不同的Path参数会被视为不同的资源名,导致容易达到SlotChain的上限

4 participants