升级Spring Boot 2.7.12遇WebMvcFilter与Prometheus圈复杂度问题
Spring Boot 2.7.12升级后WebMvcFilter与Prometheus的圈复杂度问题排查与解决
可能的根因
- Spring Boot 2.7.x版本对
WebMvcMetricsFilter(Prometheus指标采集的核心过滤器)做了逻辑增强,新增了请求路径匹配、多维度标签生成、异常分类等分支判断,导致方法圈复杂度超过了静态代码检查工具(如SonarQube)的默认阈值。 - 低版本中该过滤器仅实现基础的请求耗时、状态码采集逻辑,分支少,不会触发圈复杂度告警。
解决方案
1. 豁免框架类的静态代码检查
如果项目使用静态代码检查工具,直接将org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter加入豁免名单即可:
- 以SonarQube为例,在项目的
sonar-project.properties中添加:
注:sonar.issue.ignore.multicriteria=e1 sonar.issue.ignore.multicriteria.e1.resourceKey=**/WebMvcMetricsFilter.class sonar.issue.ignore.multicriteria.e1.ruleKey=squid:S1067squid:S1067是SonarQube中圈复杂度检查的规则ID,不同工具规则ID可能有差异,需对应调整。
2. 拆分复杂逻辑,自定义MetricsFilter
如果不想修改检查规则,可以自定义过滤器拆分原类的复杂逻辑:
public class CustomWebMvcMetricsFilter extends WebMvcMetricsFilter { public CustomWebMvcMetricsFilter(MetricsRegistry registry, WebMvcTagsProvider tagsProvider, WebMvcTagsContributor[] tagsContributors, String metricName) { super(registry, tagsProvider, tagsContributors, metricName); } // 拆分原doFilterInternal中的请求跳过判断逻辑 private boolean isExcludedRequest(HttpServletRequest request) { String uri = request.getRequestURI(); return uri.startsWith("/actuator") || uri.startsWith("/health"); } // 拆分标签构建逻辑,降低单个方法复杂度 private Tags assembleRequestTags(HttpServletRequest request, HttpServletResponse response, Object handler, Throwable ex) { Tags baseTags = getTagsProvider().getTags(request, response, handler, ex); // 可添加自定义标签逻辑 return baseTags.and("custom_tag", "value"); } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { if (isExcludedRequest(request)) { filterChain.doFilter(request, response); return; } // 调用父类逻辑完成指标采集 super.doFilterInternal(request, response, filterChain); } }
然后注册自定义过滤器替换默认实现:
@Configuration public class MetricsConfiguration { @Bean public FilterRegistrationBean<CustomWebMvcMetricsFilter> customMetricsFilter(MetricsRegistry registry, WebMvcTagsProvider tagsProvider, ObjectProvider<WebMvcTagsContributor> tagsContributors) { CustomWebMvcMetricsFilter filter = new CustomWebMvcMetricsFilter(registry, tagsProvider, tagsContributors.orderedStream().toArray(WebMvcTagsContributor[]::new), "http.server.requests"); FilterRegistrationBean<CustomWebMvcMetricsFilter> registration = new FilterRegistrationBean<>(filter); registration.setOrder(Ordered.HIGHEST_PRECEDENCE + 1); return registration; } }
3. 调整Spring Boot版本
- 若暂时无法处理代码或检查规则,可降级到Spring Boot 2.7.0(该版本
WebMvcMetricsFilter逻辑未大幅改动),但需注意同步升级安全补丁。 - 直接升级到Spring Boot 3.x版本,该版本重构了Metrics模块,
WebMvcMetricsFilter的逻辑结构更简洁,圈复杂度问题已得到优化。
内容的提问来源于stack exchange,提问作者Sashwati Das
相关产品推荐
相关产品推荐

