Spring Boot ActuatorのHTTP Client MetricsのURI tagが上限に達した

Spring Boot ActuatorとMicrometerを使っているときに、こんなwarnログが出たときのメモ。

WARN o.s.b.a.a.m.OnlyOnceLoggingDenyMeterFilter -
Reached the maximum number of URI tags for 'http.client.requests'. Are you using 'uriVariables' on RestTemplate calls?

これは、RestTemplateのmetrics(http.client.requests)のURIタグがmanagement.web.client.max-uri-tags(defaultは100)に達したため。
warnログで指摘されている通り、RestTemplateのuriVariablesを使っていなかったので、クエリパラメータごとにURIタグが作られていた。

修正前

Spring Boot: 2.1.0

String uri = UriComponentsBuilder.fromHttpUrl("http://md5.jsontest.com")
                                 .queryParam("text", text)
                                 .toUriString();
restTemplate.getForObject(uri, Map.class);

Spring Boot ActuatorのPrometheusのエンドポイントを確認すると、URLクエリパラメータごとにURIタグが作られていた。

http_client_requests_seconds_count{clientName="md5.jsontest.com",method="GET",status="200",uri="/http://md5.jsontest.com?text=aaa",} 1.0
http_client_requests_seconds_count{clientName="md5.jsontest.com",method="GET",status="200",uri="/http://md5.jsontest.com?text=bbb",} 1.0
http_client_requests_seconds_count{clientName="md5.jsontest.com",method="GET",status="200",uri="/http://md5.jsontest.com?text=ccc",} 1.0

修正後

RestTemplateを呼び出すときに、uriVariablesを使うように変更。

String uri = UriComponentsBuilder.fromHttpUrl("http://md5.jsontest.com")
                                 .queryParam("text", "{text}")
                                 .build(false)
                                 .toUriString();
restTemplate.getForObject(uri, Map.class, text);

URIタグはtemplate形式になったので、一つになった。

http_client_requests_seconds_count{clientName="md5.jsontest.com",method="GET",status="200",uri="/http://md5.jsontest.com?text={text}",} 3.0

参考

Spring BootでCaffeineのcacheごとにexpireAfterAccessを指定する

Spring BootのcacheにCaffeineを使っている場合で、cacheごとにmaximumSizeやexpireAfterAccessを指定したいときのメモ。

プロパティのspring.cache.caffeine.specにはcacheごとにexpireAfterAccessなどを設定できないので、SimpleCacheManagerを使うしかなさそう。

@Bean
public SimpleCacheManager cacheManager() {
    SimpleCacheManager cacheManager = new SimpleCacheManager();
    CaffeineCache cache1 =
                new CaffeineCache("cache1",
                                  Caffeine.newBuilder()
                                          .maximumSize(100)
                                          .expireAfterAccess(10, TimeUnit.MINUTES)
                                          .build());
    CaffeineCache cache2 =
                new CaffeineCache("cache2",
                                  Caffeine.newBuilder()
                                          .maximumSize(200)
                                          .expireAfterAccess(20, TimeUnit.MINUTES)
                                          .build());
    cacheManager.setCaches(List.of(cache1, cache2));
    return cacheManager;
}

参考

Spring DataとSpring Sessionで別々のRedisConnectionFactoryを使う

Spring Data RedisとSpring Session Data Redisで、RedisConnectionFactoryを分けたいときのメモ。
Spring Sessionで使うRedisConnectionFactoryに@SpringSessionRedisConnectionFactoryを付けると、Spring Sessionはこちらを使うようになる。

Spring Boot: 2.0.5

  @Bean
  @Primary
  public LettuceConnectionFactory redisConnectionFactory() {
    LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory();
    connectionFactory.setDatabase(0);
    return connectionFactory;
  }

  @Bean
  @SpringSessionRedisConnectionFactory
  public LettuceConnectionFactory springSessionRedisConnectionFactory() {
    LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory();
    connectionFactory.setDatabase(1);
    return connectionFactory;
  } 

参考