如安在Spring Boot中监控缓存的掷中率?

打印 上一主题 下一主题

主题 893|帖子 893|积分 2679

在 Spring Boot 中监控缓存的掷中率对于评估缓存的有用性和性能优化至关紧张。下面为你详细介绍不同缓存实现下监控缓存掷中率的方法。
1. 使用 Spring Cache 和 SimpleCacheManager

1.1 设置 SimpleCacheManager


SimpleCacheManager 是 Spring 提供的一个简单的缓存管理器,恰当开发和测试环境。首先,在设置类中设置 SimpleCacheManager。

收起
java
  1. import org.springframework.cache.CacheManager;
  2. import org.springframework.cache.annotation.EnableCaching;
  3. import org.springframework.cache.concurrent.ConcurrentMapCache;
  4. import org.springframework.cache.support.SimpleCacheManager;
  5. import org.springframework.context.annotation.Bean;
  6. import org.springframework.context.annotation.Configuration;
  7. import java.util.Arrays;
  8. @Configuration
  9. @EnableCaching
  10. public class CacheConfig {
  11.     @Bean
  12.     public CacheManager cacheManager() {
  13.         SimpleCacheManager cacheManager = new SimpleCacheManager();
  14.         cacheManager.setCaches(Arrays.asList(
  15.                 new ConcurrentMapCache("myCache")
  16.         ));
  17.         return cacheManager;
  18.     }
  19. }
复制代码
1.2 自定义缓存统计


由于 SimpleCacheManager 本身不直接提供掷中率统计功能,我们可以自定义一个包装类来实现统计。

收起
java
  1. import org.springframework.cache.Cache;
  2. import org.springframework.cache.concurrent.ConcurrentMapCache;
  3. import java.util.concurrent.atomic.AtomicInteger;
  4. public class CustomConcurrentMapCache extends ConcurrentMapCache {
  5.     private final AtomicInteger hits = new AtomicInteger(0);
  6.     private final AtomicInteger misses = new AtomicInteger(0);
  7.     public CustomConcurrentMapCache(String name) {
  8.         super(name);
  9.     }
  10.     @Override
  11.     public ValueWrapper get(Object key) {
  12.         ValueWrapper result = super.get(key);
  13.         if (result != null) {
  14.             hits.incrementAndGet();
  15.         } else {
  16.             misses.incrementAndGet();
  17.         }
  18.         return result;
  19.     }
  20.     public int getHits() {
  21.         return hits.get();
  22.     }
  23.     public int getMisses() {
  24.         return misses.get();
  25.     }
  26.     public double getHitRate() {
  27.         int total = hits.get() + misses.get();
  28.         return total == 0 ? 0 : (double) hits.get() / total;
  29.     }
  30. }
复制代码

然后在设置类中使用自定义的缓存类。

收起
java
  1. import org.springframework.cache.CacheManager;
  2. import org.springframework.cache.annotation.EnableCaching;
  3. import org.springframework.cache.support.SimpleCacheManager;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.Configuration;
  6. import java.util.Arrays;
  7. @Configuration
  8. @EnableCaching
  9. public class CacheConfig {
  10.     @Bean
  11.     public CacheManager cacheManager() {
  12.         SimpleCacheManager cacheManager = new SimpleCacheManager();
  13.         cacheManager.setCaches(Arrays.asList(
  14.                 new CustomConcurrentMapCache("myCache")
  15.         ));
  16.         return cacheManager;
  17.     }
  18. }
复制代码
1.3 监控缓存掷中率


在需要监控的地方获取自定义缓存并盘算掷中率。

收起
java
  1. import org.springframework.beans.factory.annotation.Autowired;
  2. import org.springframework.cache.Cache;
  3. import org.springframework.cache.CacheManager;
  4. import org.springframework.stereotype.Service;
  5. @Service
  6. public class CacheMonitoringService {
  7.     @Autowired
  8.     private CacheManager cacheManager;
  9.     public double getCacheHitRate(String cacheName) {
  10.         Cache cache = cacheManager.getCache(cacheName);
  11.         if (cache instanceof CustomConcurrentMapCache) {
  12.             CustomConcurrentMapCache customCache = (CustomConcurrentMapCache) cache;
  13.             return customCache.getHitRate();
  14.         }
  15.         return 0;
  16.     }
  17. }
复制代码
2. 使用 Caffeine 缓存

2.1 添加依赖


在 pom.xml 中添加 Caffeine 缓存依赖。

收起
xml
  1. <dependency>
  2.     <groupId>com.github.ben-manes.caffeine</groupId>
  3.     <artifactId>caffeine</artifactId>
  4.     <version>3.1.6</version>
  5. </dependency>
复制代码
2.2 设置 Caffeine 缓存管理器


收起
java
  1. import com.github.benmanes.caffeine.cache.Caffeine;
  2. import org.springframework.cache.CacheManager;
  3. import org.springframework.cache.annotation.EnableCaching;
  4. import org.springframework.cache.caffeine.CaffeineCacheManager;
  5. import org.springframework.context.annotation.Bean;
  6. import org.springframework.context.annotation.Configuration;
  7. import java.util.concurrent.TimeUnit;
  8. @Configuration
  9. @EnableCaching
  10. public class CacheConfig {
  11.     @Bean
  12.     public CacheManager cacheManager() {
  13.         CaffeineCacheManager cacheManager = new CaffeineCacheManager("myCache");
  14.         cacheManager.setCaffeine(caffeineCacheBuilder());
  15.         return cacheManager;
  16.     }
  17.     private Caffeine<Object, Object> caffeineCacheBuilder() {
  18.         return Caffeine.newBuilder()
  19.               .initialCapacity(100)
  20.               .maximumSize(500)
  21.               .expireAfterWrite(10, TimeUnit.MINUTES)
  22.               .recordStats();
  23.     }
  24. }
复制代码

留意,recordStats() 方法用于开启缓存统计功能。
2.3 监控缓存掷中率


收起
java
  1. import com.github.benmanes.caffeine.cache.Cache;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.cache.CacheManager;
  4. import org.springframework.cache.caffeine.CaffeineCache;
  5. import org.springframework.stereotype.Service;
  6. @Service
  7. public class CacheMonitoringService {
  8.     @Autowired
  9.     private CacheManager cacheManager;
  10.     public double getCacheHitRate(String cacheName) {
  11.         org.springframework.cache.Cache springCache = cacheManager.getCache(cacheName);
  12.         if (springCache instanceof CaffeineCache) {
  13.             CaffeineCache caffeineCache = (CaffeineCache) springCache;
  14.             Cache<Object, Object> nativeCache = caffeineCache.getNativeCache();
  15.             return nativeCache.stats().hitRate();
  16.         }
  17.         return 0;
  18.     }
  19. }
复制代码
3. 使用 Redis 缓存

3.1 添加依赖


在 pom.xml 中添加 Redis 缓存依赖。

收起
xml
  1. <dependency>
  2.     <groupId>org.springframework.boot</groupId>
  3.     <artifactId>spring-boot-starter-data-redis</artifactId>
  4. </dependency>
复制代码
3.2 设置 Redis 缓存管理器


收起
java
  1. import org.springframework.cache.CacheManager;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.data.redis.cache.RedisCacheConfiguration;
  5. import org.springframework.data.redis.cache.RedisCacheManager;
  6. import org.springframework.data.redis.connection.RedisConnectionFactory;
  7. import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
  8. import org.springframework.data.redis.serializer.RedisSerializationContext;
  9. import org.springframework.data.redis.serializer.StringRedisSerializer;
  10. import java.time.Duration;
  11. @Configuration
  12. public class CacheConfig {
  13.     @Bean
  14.     public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
  15.         RedisCacheConfiguration cacheConfig = RedisCacheConfiguration.defaultCacheConfig()
  16.               .entryTtl(Duration.ofMinutes(10))
  17.               .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
  18.               .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
  19.         return RedisCacheManager.builder(redisConnectionFactory)
  20.               .cacheDefaults(cacheConfig)
  21.               .build();
  22.     }
  23. }
复制代码
3.3 监控缓存掷中率


Redis 本身提供了一些命令来监控缓存掷中率,例如 INFO stats 命令可以获取 keyspace_hits 和 keyspace_misses 信息。在 Spring Boot 中,可以使用 RedisTemplate 来实行这些命令。

收起
java
  1. import org.springframework.beans.factory.annotation.Autowired;
  2. import org.springframework.data.redis.connection.RedisConnection;
  3. import org.springframework.data.redis.core.RedisTemplate;
  4. import org.springframework.stereotype.Service;
  5. import java.util.Map;
  6. @Service
  7. public class CacheMonitoringService {
  8.     @Autowired
  9.     private RedisTemplate<String, Object> redisTemplate;
  10.     public double getRedisCacheHitRate() {
  11.         RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
  12.         String info = new String(connection.info("stats"));
  13.         String[] lines = info.split("\r\n");
  14.         long hits = 0;
  15.         long misses = 0;
  16.         for (String line : lines) {
  17.             if (line.startsWith("keyspace_hits:")) {
  18.                 hits = Long.parseLong(line.split(":")[1]);
  19.             } else if (line.startsWith("keyspace_misses:")) {
  20.                 misses = Long.parseLong(line.split(":")[1]);
  21.             }
  22.         }
  23.         long total = hits + misses;
  24.         return total == 0 ? 0 : (double) hits / total;
  25.     }
  26. }
复制代码

通过以上方法,你可以在 Spring Boot 中对不同的缓存实现举行掷中率监控,从而更好地优化缓存设置和体系性能。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

石小疯

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表