南宁网站设计推广,wordpress菜单种类,怎么看网站用的什么后台,网站中转页基于Spring Boot的多级缓存架构实现
以下是一个基于Spring Boot的多级缓存架构实现示例 多级缓存架构实现方案
1. 依赖配置#xff08;pom.xml#xff09;
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-star…基于Spring Boot的多级缓存架构实现
以下是一个基于Spring Boot的多级缓存架构实现示例 多级缓存架构实现方案
1. 依赖配置pom.xml
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-cache/artifactId
/dependency
dependencygroupIdcom.github.ben-manes.caffeine/groupIdartifactIdcaffeine/artifactId
/dependency
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId
/dependency2. 缓存配置类
Configuration
EnableCaching
public class MultiLevelCacheConfig {// 一级缓存本地缓存Beanpublic CacheManager caffeineCacheManager() {CaffeineCacheManager manager new CaffeineCacheManager();manager.setCaffeine(Caffeine.newBuilder().maximumSize(1000).expireAfterWrite(30, TimeUnit.SECONDS)); // 本地缓存比Redis缓存更短return manager;}// 二级缓存Redis缓存Beanpublic CacheManager redisCacheManager(RedisConnectionFactory factory) {RedisCacheConfiguration config RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(5)).serializeValuesWith(SerializationPair.fromSerializer(RedisSerializer.json()));return RedisCacheManager.builder(factory).cacheDefaults(config).transactionAware().build();}// 组合缓存管理器BeanPrimarypublic CacheManager multiLevelCacheManager(Qualifier(caffeineCacheManager) CacheManager level1,Qualifier(redisCacheManager) CacheManager level2) {return new MultiLevelCacheManager(level1, level2);}
}3. 多级缓存管理器实现
public class MultiLevelCacheManager implements CacheManager {private final CacheManager level1; // 本地缓存private final CacheManager level2; // Redis缓存private final ConcurrentMapString, Cache cacheMap new ConcurrentHashMap();public MultiLevelCacheManager(CacheManager level1, CacheManager level2) {this.level1 level1;this.level2 level2;}Overridepublic Cache getCache(String name) {return cacheMap.computeIfAbsent(name, key - new MultiLevelCache(level1.getCache(name), level2.getCache(name)));}Overridepublic CollectionString getCacheNames() {return Stream.concat(level1.getCacheNames().stream(),level2.getCacheNames().stream()).collect(Collectors.toSet());}// 多级缓存实现static class MultiLevelCache implements Cache {private final Cache level1;private final Cache level2;private final String name;public MultiLevelCache(Cache level1, Cache level2) {this.level1 level1 ! null ? level1 : new NoOpCache();this.level2 level2 ! null ? level2 : new NoOpCache();this.name level1.getName() : level2.getName();}Overridepublic String getName() {return name;}Overridepublic Object getNativeCache() {return this;}Overridepublic ValueWrapper get(Object key) {// 先查一级缓存ValueWrapper value level1.get(key);if (value null) {// 二级缓存查询value level2.get(key);if (value ! null) {// 回填一级缓存level1.put(key, value.get());}}return value;}Overridepublic T T get(Object key, ClassT type) {// 实现逻辑类似get方法T value level1.get(key, type);if (value null) {value level2.get(key, type);if (value ! null) {level1.put(key, value);}}return value;}Overridepublic void put(Object key, Object value) {// 同时写入两级缓存level1.put(key, value);level2.put(key, value);}Overridepublic void evict(Object key) {// 同时清除两级缓存level1.evict(key);level2.evict(key);}Overridepublic void clear() {level1.clear();level2.clear();}}// 空缓存实现容错static class NoOpCache implements Cache {// 实现基础的Cache方法返回空值}
}4. 业务层使用
Service
public class ProductService {Cacheable(value products, key #id)public Product getProduct(Long id) {// 数据库查询逻辑return productRepository.findById(id).orElseThrow(() - new NotFoundException(Product not found));}CacheEvict(value products, key #product.id)public void updateProduct(Product product) {productRepository.save(product);}
}5. 配置说明application.yml
spring:cache:multi-level:level1:ttl: 30s # 本地缓存时间max-size: 1000level2:ttl: 5m # Redis缓存时间redis:host: redis-cluster.prodport: 6379timeout: 2000ms关键实现要点
缓存层级策略 #mermaid-svg-CpqFHSVvOVkfqyka {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-CpqFHSVvOVkfqyka .error-icon{fill:#552222;}#mermaid-svg-CpqFHSVvOVkfqyka .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-CpqFHSVvOVkfqyka .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-CpqFHSVvOVkfqyka .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-CpqFHSVvOVkfqyka .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-CpqFHSVvOVkfqyka .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-CpqFHSVvOVkfqyka .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-CpqFHSVvOVkfqyka .marker{fill:#333333;stroke:#333333;}#mermaid-svg-CpqFHSVvOVkfqyka .marker.cross{stroke:#333333;}#mermaid-svg-CpqFHSVvOVkfqyka svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-CpqFHSVvOVkfqyka .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-CpqFHSVvOVkfqyka text.actortspan{fill:black;stroke:none;}#mermaid-svg-CpqFHSVvOVkfqyka .actor-line{stroke:grey;}#mermaid-svg-CpqFHSVvOVkfqyka .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-CpqFHSVvOVkfqyka .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-CpqFHSVvOVkfqyka #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-CpqFHSVvOVkfqyka .sequenceNumber{fill:white;}#mermaid-svg-CpqFHSVvOVkfqyka #sequencenumber{fill:#333;}#mermaid-svg-CpqFHSVvOVkfqyka #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-CpqFHSVvOVkfqyka .messageText{fill:#333;stroke:#333;}#mermaid-svg-CpqFHSVvOVkfqyka .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-CpqFHSVvOVkfqyka .labelText,#mermaid-svg-CpqFHSVvOVkfqyka .labelTexttspan{fill:black;stroke:none;}#mermaid-svg-CpqFHSVvOVkfqyka .loopText,#mermaid-svg-CpqFHSVvOVkfqyka .loopTexttspan{fill:black;stroke:none;}#mermaid-svg-CpqFHSVvOVkfqyka .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-CpqFHSVvOVkfqyka .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-CpqFHSVvOVkfqyka .noteText,#mermaid-svg-CpqFHSVvOVkfqyka .noteTexttspan{fill:black;stroke:none;}#mermaid-svg-CpqFHSVvOVkfqyka .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-CpqFHSVvOVkfqyka .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-CpqFHSVvOVkfqyka .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-CpqFHSVvOVkfqyka .actorPopupMenu{position:absolute;}#mermaid-svg-CpqFHSVvOVkfqyka .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-CpqFHSVvOVkfqyka .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-CpqFHSVvOVkfqyka .actor-man circle,#mermaid-svg-CpqFHSVvOVkfqyka line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-CpqFHSVvOVkfqyka :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Client Level1 Level2 DB 查询缓存 命中返回 查询二级缓存 返回结果 返回结果 查询数据库 返回数据 回填数据 返回数据 alt [二级缓存未命中] alt [未命中] Client Level1 Level2 DB 一致性保障
写操作同时清除两级缓存CacheEvict读操作二级缓存命中后自动回填一级缓存TTL策略一级缓存TTL30s 二级缓存TTL5m
性能优化
本地缓存使用Caffeine高性能缓存库异步回填可扩展为异步加载需自定义CacheLoader批量操作支持Cacheable的批量查询优化 扩展建议
缓存预热
PostConstruct
public void preloadHotData() {// 加载热点数据到缓存hotProducts.forEach(product - cacheManager.getCache(products).put(product.getId(), product));
}监控集成
Bean
public MeterRegistryCustomizerMeterRegistry cacheMetrics() {return registry - {CaffeineCacheManager caffeine context.getBean(CaffeineCacheManager.class);RedisCacheManager redis context.getBean(RedisCacheManager.class);// 注册Caffeine监控CacheMetrics.monitor(registry, caffeine, level1);// 注册Redis监控CacheMetrics.monitor(registry, redis, level2);};
}防雪崩策略
// 在MultiLevelCache.get方法中添加
ValueWrapper get(Object key) {try {// 添加分布式锁检查if (lockManager.tryLock(key)) {// 实际查询逻辑}} finally {lockManager.unlock(key);}
}