无论如何从 AsyncResttemplate 获取 http.client.requests 指标?

Posted

技术标签:

【中文标题】无论如何从 AsyncResttemplate 获取 http.client.requests 指标?【英文标题】:Is there anyway to get http.client.requests metrics from AsyncResttemplate? 【发布时间】:2020-02-25 12:07:06 【问题描述】:

我正在尝试通过 micrometer 和 prometheus 监控我的 Spring Boot 应用程序的其余模板指标。 当我使用用 ResttemplateBuilder 构建的 Resttemplate 并用于调用另一个 api 时,它确实获得了预期的 http.client.requests 指标。 但是对于 AsyncResttemplate,当我使用 AsyncResttemplate 创建并使用它来调用另一个 api 时,它没有提供任何 http.client.requests 指标。

这是我创建 AsyncResttemplate bean 时的代码

    @Bean
    public AsyncRestTemplate asyncRestTemplate()
        return new AsyncRestTemplate();
    

这是我使用异步调用另一个 api 时的代码

    public ListenableFuture async() 
        ListenableFuture<ResponseEntity<AccountResponse>> accountResponseList = asyncRestTemplate.exchange(accountUrl, HttpMethod.GET, new HttpEntity<>(new HttpHeaders()), AccountResponse.class);
        accountResponseList.addCallback(new ListenableFutureCallback<ResponseEntity<AccountResponse>>() 
            @Override
            public void onSuccess(ResponseEntity<AccountResponse> accountResponseResponseEntity) 
                System.out.println("Success");
            

            @Override
            public void onFailure(Throwable throwable) 
                System.out.println("Failure");
            
        );
        return accountResponseList;
    

这些是pom.xml中导入的相关依赖

<dependency>
      <groupId>io.micrometer</groupId>
      <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

这是我期望从 micrometer-prometheus 指标中得到的结果

# HELP http_client_requests_seconds Timer of RestTemplate operation
# TYPE http_client_requests_seconds summary
http_client_requests_seconds_countapplication="$spring.application.name",clientName="localhost",method="GET",status="200",uri="/getAllAccount", 1.0
http_client_requests_seconds_sumapplication="$spring.application.name",clientName="localhost",method="GET",status="200",uri="/getAllAccount", 0.0242929
# HELP http_client_requests_seconds_max Timer of RestTemplate operation
# TYPE http_client_requests_seconds_max gauge
http_client_requests_seconds_maxapplication="$spring.application.name",clientName="localhost",method="GET",status="200",uri="/getAllAccount", 0.0242929

以上指标来自 ResttemplateBuilder,有没有办法也可以为 AsyncRestTemplate 获取这些指标?

更新:根据 M. Deinum 的建议,我将 bean 更改为

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder)
        return builder.setConnectTimeout(Duration.ofSeconds(500)).build();
    

    @Bean
    public AsyncRestTemplate asyncRestTemplate(RestTemplate restTemplate)
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        SimpleAsyncTaskExecutor asyncTaskExecutor = new SimpleAsyncTaskExecutor();
        asyncTaskExecutor.setConcurrencyLimit(10);
        requestFactory.setTaskExecutor(asyncTaskExecutor);
        return new AsyncRestTemplate(requestFactory, restTemplate);
    

但仍然没有从异步调用中获得任何 http.client.requests

【问题讨论】:

使用RestTemplateBuilder创建RestTemplate并使用@构造AsyncRestTemplateAsyncRestTemplate只是RestTemplate的包装)。 【参考方案1】:

应该这样做。

@Bean
public AsyncRestTemplate asyncRestTemplate(RestTemplateBuilder builder)
  RestTemplate rest = builder.build();
  AsyncClientHttpRequestFactory requestFactory = (AsyncClientHttpRequestFactory) rest.getRequestFactory();
  return new AsyncRestTemplate(requestFactory, rest);

这将重用现有配置。 AsyncRestTemplate 只是 RestTemplate 的一个包装器,将它与一个 `TaskExecutor.

注意:请注意,自 Spring 5 起,AsyncRestTemplate 已被弃用,并且可能在不久的将来某个地方被删除!

【讨论】:

我试了一下,得到了这个异常Caused by: java.lang.ClassCastException: org.springframework.http.client.InterceptingClientHttpRequestFactory cannot be cast to org.springframework.http.client.AsyncClientHttpRequestFactory 该死,没有考虑包装。使用new SimpleClientHttpRequestFactory() 而不是从RestTemplate 获取它。除非您自己已经配置了另一个 ClientHttpRequestFactory,否则请重用并注入那个。 尝试了这个配置并且能够拨打电话,但我仍然无法获得 http.client.requests 指标。 那么您真的使用构建器来处理RestTEmplate 还是进行了一些额外的配置?也许像 bean 一样定义它? 我已经发布了我更改的内容,但仍未从 http.client.requests 获得任何指标

以上是关于无论如何从 AsyncResttemplate 获取 http.client.requests 指标?的主要内容,如果未能解决你的问题,请参考以下文章

在测试 AsyncRestTemplate 时防止预期已经声明异常

在测试AsyncRestTemplate时,防止已经声明异常的期望

将 OAuth2RestTemplate 公开为 AsyncRestTemplate

使用AsyncRestTemplate 来实现异步的回调

带有 AsyncRestTemplate Netty 客户端的 Spring Boot 失败

Spring 的 AsyncRestTemplate 不适用于压缩内容,获取压缩内容而不是 json 对象