ComponentScan排除过滤器致http_server_request Actuator指标缺失排查
我们有一个基于Spring的简易库,在新的专属包中添加了新实现,其主配置类代码如下:
@Configuration public class ChangesConfig { public static final String CONFIG_CHANGE_PREFIX = "CONFIG_CHANGE_"; public static final String CONFIG_CHANGE_STANDARD_OUTPUT = "CONFIG_CHANGE_STANDARD_OUTPUT"; @Bean GcpProjectIdProvider gcpProjectIdProvider() { return new DefaultGcpProjectIdProvider(); } @Bean public Builder BuilderConfig(GcpProjectIdProvider gcpProjectIdProvider) { return new CachingBuilder(new DefaultBuilder(gcpProjectIdProvider)); } @Bean public ChangeProvider ChangeProvider(ConfigurableEnvironment configurableEnvironment, Builder BuilderConfig) { Properties props = new Properties(); MutablePropertySources mutablePropertySources = configurableEnvironment.getPropertySources(); List<String> properties = StreamSupport.stream(mutablePropertySources.spliterator(), false) .filter(EnumerablePropertySource.class::isInstance) .map(ps -> ((EnumerablePropertySource<?>) ps).getPropertyNames()) .flatMap(Arrays::stream) .filter(propName -> propName.startsWith(CONFIG_CHANGE_PREFIX)) .collect(Collectors.toList()); if(properties.isEmpty()) return new NoOpChangeProvider(); properties.forEach(propName -> props.setProperty(propName.substring(CONFIG_CHANGE_PREFIX.length()).toLowerCase(), configurableEnvironment.getProperty(propName))); if(properties.size() == 1 && properties.contains(CONFIG_CHANGE_STANDARD_OUTPUT)) { return new StandardOutputChangeProvider(); } return new ChangeProviderImpl(props, BuilderConfig); } @Bean public ConfigRecorder ConfigRecorder(ChangeProvider ChangeProvider) { return new ConfigRecorderImpl(ChangeProvider); } }
构建库的新版本后,上游服务升级版本时测试失败,原启动类代码:
@Slf4j @SpringBootApplication(exclude = {R2dbcAutoConfiguration.class}, scanBasePackages = "com.abc") public class Application { public static void main(String[] args) { ReactorDebugAgent.init(); SpringApplication.run(Application.class, args); } }
我们在@ComponentScan中排除特定包后,测试通过且构建正常,修改后的启动类:
@Slf4j @SpringBootApplication(exclude = {R2dbcAutoConfiguration.class}) @ComponentScan(basePackages = "com.abc", excludeFilters= {@ComponentScan.Filter(type= FilterType.REGEX, pattern={"com.abc.bcd.def..*"})}) public class Application { public static void main(String[] args) { ReactorDebugAgent.init(); SpringApplication.run(Application.class, args); } }
但发现仅http_server_request Actuator指标丢失,移除excludeFilters后指标恢复正常。尝试多种@ComponentScan修改均无效,请问可能的原因是什么?
1. 排除规则误覆盖了指标收集相关组件
你设置的排除规则com.abc.bcd.def..*可能误匹配到了负责http_server_request指标收集的组件:
- 要么是项目自定义的、继承自
WebMvcMetricsFilter/WebFluxMetricsFilter的过滤器,或是实现MeterBinder的Bean正好在该包路径下,排除后无法加载,导致HTTP请求指标无法被收集; - 要么是库的新实现中,
ChangesConfig所在包与Actuator指标相关组件的路径有重叠,排除规则误移除了必要的Bean。
2. @ComponentScan与@SpringBootApplication扫描规则冲突
显式指定@ComponentScan会覆盖@SpringBootApplication默认的扫描逻辑(默认扫描启动类所在包及其子包)。如果Actuator自动配置类或相关指标Bean不在com.abc包下,加上排除规则的影响,会导致自动配置的加载逻辑异常,进而丢失指标。
另外,@SpringBootApplication本身已包含@ComponentScan,显式添加后可能打乱自动配置类的依赖链,比如某些Actuator自动配置依赖的Bean被排除,无法完成初始化。
3. 库的新实现包含干扰指标收集的组件
库在新包中新增的实现,可能存在与Actuator指标收集冲突的Bean(比如自定义Filter、Interceptor或MeterRegistryCustomizer)。这些Bean被扫描时会干扰http_server_request指标的生成逻辑;而排除该包后,虽然解决了测试失败问题,但同时也移除了原本适配Actuator指标的组件,最终导致指标丢失。
4. 排除规则导致自动配置条件失效
Spring Boot自动配置依赖特定Bean的存在性触发,比如HttpMetricsAutoConfiguration需要检测到MeterRegistry和相关Web组件才会生效。如果排除规则导致某个关键Bean无法被扫描,会让自动配置的判断条件不满足,从而不加载对应的指标收集逻辑。
- 检查
com.abc.bcd.def包下所有类,确认是否包含与Actuator指标、Web请求拦截/过滤相关的组件; - 开启Spring Boot调试日志(
logging.level.org.springframework=DEBUG),对比添加/移除excludeFilters时,Actuator相关Bean的初始化差异; - 缩小排除范围,比如只排除库中新添加的特定类而非整个包,验证是否能同时解决测试失败和指标丢失问题;
- 查看库新实现中是否有与
MeterRegistry、MetricsFilter相关的代码,确认这些组件是否会影响Actuator指标收集。
内容的提问来源于stack exchange,提问作者SRJ

