从spring boot 2.7.5迁移到spring boot 3.0.1后。
度量http.client.requests上的标记URI在所有情况下都具有值none。
我们像 那样构建restTemplate的URIURI uri = UriComponentsBuilder.fromUri(restTemplate.getUriTemplateHandler().expand("/hello"))
.build()
.toUri();
return restTemplate.getForObject(uri, String.class);
我习惯这样做,因为要添加查询参数,我认为这样更容易阅读和管理。
为了复制它,我在这个存储库中创建了两个小应用程序一个在spring启动2.7.7上,另一个在3.0.1上
我发现它与spring 6上的新Observability有关,并与spring boot上的这个问题有关。
Spring boot 2自定义UriTemplateHandler并将urlTemplate存储在threadlocaldeque>中。并使用这个deque标记uri。
从文档中我知道我可以通过提供一个新的@Bean ClientRequestObservationConvention来增强标签。
我也可以使用org.springframework.web.client.RestTemplate#getForObject(java.lang. lang.)String, java.lang.Class, java.util.Map<java.lang.String,?>)。像
return restTemplate.getForObject("/hello", String.class);
但我想知道是否有一种方法来获得以前的行为,仍然使用org.springframework.web.client.RestTemplate#getForEntity(java.net.URI, java.lang.Class).
在Spring Boot 3和可观察性改进之前,RestTemplate
确实会使用完整的请求URI。标签。这是错误的,因为URI值在应用程序中没有边界,并且可能导致度量系统中的基数爆炸。
例如,客户端可以用"/user/12"
,"/user/23"
等来报告uri标签。正确的标记应该是低基数,并使用类似"/user/{userId}"
的请求模式。
在Spring Boot 2。x版本中,出于兼容性原因,我们没有改变这种行为,而是添加了一个MeterFilter
,一旦达到阈值就停止记录指标。从Spring Framework 6开始,工具直接在RestTemplate
中构建。只有当RestTemplate
方法接受String模板时才会记录此标记,如您所注意到的restTemplate.getForObject("/hello", String.class)
。
您可以通过提供自己的ClientRequestObservationConvention
恢复到以前的行为(有关更多信息,请参阅迁移wiki),但请注意,您还需要确保基数爆炸不会成为应用程序中的问题。
请看这个春季启动问题看起来很相似。