You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Caffeine Cache时manage/metrics端点cache.puts计数始终为0的问题

问题描述

使用Spring Boot 2.7.2和Caffeine 2.8.5,缓存功能正常,但/actuator/metrics/cache.puts计数始终为0,其他缓存指标(cache.eviction.weight、cache.evictions、cache.gets、cache.size)均显示正常。

配置代码如下:

@Configuration
@ConfigurationProperties(prefix = "importantcache")
public class CaffeineCacheConfig {

   private Long maxSize;
   private Duration expire;
   
  public Long getMaxSize() {
    return maxSize;
  }
  public void setMaxSize(Long maxSize) {
    this.maxSize = maxSize;
  }
  public Duration getExpire() {
    return expire;
  }
  public void setExpire(Duration expire) {
    this.expire = expire;
  }

}
@Component
@EnableCaching
public class CaffeineCache {

  private final CaffeineCacheConfig caffeineCacheConfig;
  
  @Autowired
  public CaffeineCache(CaffeineCacheConfig caffeineCacheConfig) {
      this.caffeineCacheConfig = caffeineCacheConfig;
  }
  
 @Bean 
 public CacheManager cacheManager() {
  CaffeineCacheManager cacheManager = new CaffeineCacheManager(
          "cache1",
          "cache2",
          "cache3"
  );
  cacheManager.setCaffeine(caffeineCacheBuilder());
  
  return cacheManager;
 }

 Caffeine<Object, Object> caffeineCacheBuilder() {
   Long size = 1000L;
   Duration expire =  Duration.parse("PT1H"); 
   
   if (caffeineCacheConfig.getMaxSize() != null) {
     size = caffeineCacheConfig.getMaxSize();
   }
   if (caffeineCacheConfig.getExpire() != null) {
     expire = caffeineCacheConfig.getExpire();
   }

   return Caffeine.newBuilder()
     .maximumSize(size)
     .expireAfterWrite(expire)
     .recordStats();
 }
}

尝试过的另一种cacheManager()实现:

@Bean
public CacheManager cacheManager(MeterRegistry meterRegistry) {
  CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager() {
    protected com.github.benmanes.caffeine.cache.Cache<Object, Object> createNativeCaffeineCache(String name) {
      return CaffeineCacheMetrics.monitor(meterRegistry, super.createNativeCaffeineCache(name), name);
    }

  };
  caffeineCacheManager.setCaffeine(caffeineCacheBuilder());

  return caffeineCacheManager;
}
解决方案

1. 确认缓存写入的触发逻辑

Spring Cache的@Cacheable仅在缓存未命中且执行方法逻辑后才会触发put操作,对应cache.puts指标。如果你的场景大部分是缓存命中,或未通过Spring Cache注解/API主动写入,cache.puts自然不会增长。

  • 验证方法:调用一个必然缓存未命中的方法,或直接使用Cache.put(key, value)API写入数据,再检查指标是否更新。

2. 修复缓存指标的绑定逻辑

Spring Boot 2.7.x默认的Caffeine指标采集可能遗漏puts统计,需要确保CaffeineCacheMetrics正确绑定缓存实例:

@Bean
public CacheManager cacheManager(MeterRegistry meterRegistry) {
    CaffeineCacheManager cacheManager = new CaffeineCacheManager("cache1", "cache2", "cache3");
    cacheManager.setCaffeine(caffeineCacheBuilder());
    
    // 为每个缓存实例手动注册Metrics
    cacheManager.getCacheNames().forEach(cacheName -> {
        Cache cache = cacheManager.getCache(cacheName);
        if (cache instanceof CaffeineCache) {
            com.github.benmanes.caffeine.cache.Cache<Object, Object> nativeCache = 
                ((CaffeineCache) cache).getNativeCache();
            CaffeineCacheMetrics.monitor(meterRegistry, nativeCache, cacheName);
        }
    });
    
    return cacheManager;
}

3. 升级Caffeine版本适配Spring Boot

Caffeine 2.8.5与Spring Boot 2.7.2存在轻微适配问题,建议升级到Spring Boot 2.7.x推荐的稳定版本2.9.3:

<!-- pom.xml -->
<dependency>
    <groupId>com.github.benmanes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
    <version>2.9.3</version>
</dependency>

4. 启用Caffeine原生日志验证统计

在application.properties中添加日志配置,直接查看Caffeine原始统计数据:

logging.level.com.github.benmanes.caffeine.cache=DEBUG

执行缓存写入操作后,查看日志中的CacheStats输出,检查totalPuts()是否大于0。如果原生统计有值但Spring Metrics未体现,说明指标绑定环节存在问题。

5. 用原生API验证统计逻辑

绕过Spring Cache,直接使用Caffeine原生API写入,验证统计是否正常:

@Autowired
private CacheManager cacheManager;

public void testCachePuts() {
    Cache cache = cacheManager.getCache("cache1");
    if (cache instanceof CaffeineCache) {
        com.github.benmanes.caffeine.cache.Cache<Object, Object> nativeCache = 
            ((CaffeineCache) cache).getNativeCache();
        // 写入测试数据
        for (int i = 0; i < 10; i++) {
            nativeCache.put("test-key-" + i, "test-value-" + i);
        }
        // 打印原生统计
        CacheStats stats = nativeCache.stats();
        System.out.println("原生统计totalPuts: " + stats.totalPuts());
    }
}

如果原生统计的totalPuts()正确,但Spring Metrics的cache.puts仍为0,需重点排查指标注册逻辑。

内容的提问来源于stack exchange,提问作者pesto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 22:35:18