配置Pooled ConnectionProvider的HTTP客户端指标导致响应式Web服务启动失败
错误原因
- 你的
BeanPostProcessor用法完全不符合规范:BeanPostProcessor会处理Spring上下文内所有Bean的初始化流程,你不管入参是什么Bean,都直接返回新建的HttpClient实例,会把上下文中原有的所有Bean覆盖,直接破坏上下文结构。 - 你在Bean初始化阶段直接调用
block()执行HTTP请求,此时Spring上下文还未完成初始化,链路追踪组件的braveTracerBean还在创建过程中,而HttpClient默认会集成链路追踪能力,调用时会尝试获取还未初始化完成的braveTracer,直接触发循环引用报错。 - 你自定义的
postProcessAfterInitializationA方法名拼写错误,不符合BeanPostProcessor接口的方法定义,本来也不会被Spring正常调用。
正确配置Reactor Netty连接池指标(Spring Cloud Gateway环境)
你要的4个连接池指标reactor.netty.connection.provider.*只要开启HttpClient的metrics功能就会自动上报到Micrometer,无需额外开发采集逻辑,按照以下步骤配置即可:
- 配置MeterFilter限制HttpClient的URI标签数量,避免指标爆炸,直接注册为Spring Bean:
import io.micrometer.core.instrument.MeterFilter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MetricsConfig { @Bean public MeterFilter httpClientUriTagLimitFilter() { return MeterFilter.maximumAllowableTags("reactor.netty.http.client", "URI", 100, MeterFilter.deny()); } }
- 定制Spring Cloud Gateway内置的HttpClient实例(Gateway转发请求默认使用该实例),开启指标并配置URI模板化:
import org.springframework.cloud.gateway.config.HttpClientCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import reactor.netty.http.client.HttpClient; @Configuration public class GatewayHttpClientConfig { @Bean public HttpClientCustomizer gatewayHttpClientCustomizer() { return httpClient -> httpClient.metrics(true, uri -> { if (uri.startsWith("/stream/")) { return "/stream/{n}"; } else if (uri.startsWith("/bytes/")) { return "/bytes/{n}"; } return uri; }); } }
配置完成后,直接从/actuator/metrics或/actuator/prometheus端点即可查询到你需要的4个连接池指标。
3. 如果你需要单独的全局HttpClient实例做其他业务请求,直接注册为Bean即可,不要在初始化阶段执行请求:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import reactor.netty.http.client.HttpClient; @Configuration public class CustomHttpClientConfig { @Bean public HttpClient businessHttpClient() { return HttpClient.create() .metrics(true, uri -> { if (uri.startsWith("/stream/")) return "/stream/{n}"; else if (uri.startsWith("/bytes/")) return "/bytes/{n}"; return uri; }); } }
使用时直接注入该Bean即可,调用逻辑放在业务代码中执行,不要在配置类初始化阶段调用block()等阻塞API。
内容的提问来源于stack exchange,提问作者Deepti
相关产品推荐
相关产品推荐

