在我们的 Spring Boot 应用程序中,我们使用 actuator 和集成的 prometheus。现在我们想要收集 HTTP 客户端指标。
在我们的场景中,我们使用 OpenAPI 规范来定义其余接口。使用 OpenApi 生成器生成客户端。为此,我们使用 Maven 插件 org.openapitools:openapi-generator-maven-plugin:6.0.1
通常,收集上述指标是通过 WebClientAutoConfiguration 配置的(请参阅 https://docs.spring.io/spring-boot/docs/2.1.9.RELEASE/reference/html/product-ready-metrics.html#product -ready-metrics-http-clients)。但是,由于 OpenAPI 生成器生成的 Web 客户端构建器不是 Spring Bean,因此 Spring 的自动配置不起作用:
WebClientAutoConfiguration#webClientBuilder matched:
- @ConditionalOnMissingBean (types: org.springframework.web.reactive.function.client.WebClient$Builder; SearchStrategy: all) did not find any beans (OnBeanCondition)
原因在于 OpenAPI 生成器。它生成一个静态方法并且没有 Spring Bean:
public static WebClient.Builder buildWebClientBuilder(ObjectMapper mapper) {
ExchangeStrategies strategies = ExchangeStrategies
.builder()
.codecs(clientDefaultCodecsConfigurer -> {
clientDefaultCodecsConfigurer.defaultCodecs().jackson2JsonEncoder(new Jackson2JsonEncoder(mapper, MediaType.APPLICATION_JSON));
clientDefaultCodecsConfigurer.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder(mapper, MediaType.APPLICATION_JSON));
}).build();
WebClient.Builder webClientBuilder = WebClient.builder().exchangeStrategies(strategies);
return webClientBuilder;
}
我认为没有机会扩展 WebClient 来收集 webflux 客户端指标。您知道如何在使用 OpenAPI 客户端生成器时收集 HTTP 客户端指标吗?是否有任何我错过的 OpenApi 生成器配置可以帮助我?
或者是修改开放 API 生成器 Mustache 模板的唯一方法? (https://openapi-generator.tech/docs/templated#modifying-templates)
由于更改胡子模板对我来说不是一个选择,因此我找到了一个非常好且简单的解决方案来解决该问题。
我定义并添加了一个 ExchangeFilterFunction。
这些片段应该有助于理解解决方案:
添加maven依赖
<dependency>
<!-- E.g. class MetricsWebClientFilterFunction + autoconfig for MetricsProperties -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
</dependency>
<dependency>
<!-- class MeterRegistry -->
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
</dependency>
额外所需bean的定义
@ConditionalOnMissingBean
@Bean
MetricsWebClientFilterFunction metricsWebClientFilterFunction(MeterRegistry meterRegistry,
MetricsProperties properties, WebClientExchangeTagsProvider webClientExchangeTagsProvider) {
MetricsProperties.Web.Client.ClientRequest request = properties.getWeb().getClient().getRequest();
return new MetricsWebClientFilterFunction(meterRegistry, webClientExchangeTagsProvider,
request.getMetricName(), request.getAutotime());
}
@ConditionalOnMissingBean
@Bean
WebClientExchangeTagsProvider defaultWebClientExchangeTagsProvider() {
return new DefaultWebClientExchangeTagsProvider();
}
创建 ApiClient bean 并添加过滤器
@Bean
public ApiClient apiClientRefJPers(@Autowired MetricsWebClientFilterFunction metricsWebClientFilterFunction) {
final WebClient.Builder webClientBuilder = ApiClient.buildWebClientBuilder().filter(metricsWebClientFilterFunction);
ApiClient client = new ApiClient(webClientBuilder.build());
// ...
// client.setBasePath(...);
// ...
return client;
}