SpringBoot EhCache 缓存

一、EhCache核心原理

  1. 层级存储

    • 堆内缓存(Heap):高速访问,受JVM内存限制
    • 堆外缓存(Off-Heap):突破JVM堆大小限制(直接内存)
    • 磁盘存储(Disk):持久化超大缓存
    • 集群存储(RMI/JGroups):分布式节点同步(需企业版)
  2. 数据过期策略

    • LRU(最近最少使用)
    • LFU(最不经常使用)
    • FIFO(先进先出)
    • 基于创建/访问时间的TTL(生存时间)
  3. 缓存工作流程

    是 否 方法调用 缓存是否存在? 返回缓存结果 执行方法 结果存入EhCache 返回结果


二、Spring Boot集成步骤

1. 添加依赖
xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
    <groupId>org.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <version>3.10.0</version>
</dependency>
2. 配置文件ehcache.xml
xml 复制代码
<config xmlns='http://www.ehcache.org/v3'>
    <cache alias="books">
        <heap unit="entries">1000</heap>  <!-- 堆内最多1000个条目 -->
        <ttl unit="seconds">60</ttl>     <!-- 60秒后过期 -->
    </cache>
</config>
3. 启用缓存配置类
java 复制代码
@Configuration
@EnableCaching
public class CacheConfig {
    @Bean
    public JCacheManagerCustomizer cacheManagerCustomizer() {
        return cm -> {
            cm.createCache("books", 
                Eh107Configuration.fromEhcache(
                    CacheConfigurationBuilder.newCacheConfigurationBuilder(
                        Long.class, 
                        Book.class,
                        ResourcePoolsBuilder.heap(1000).build()
                    )
                )
            );
        };
    }
}

三、核心注解详解

注解 作用 示例
@Cacheable 方法结果缓存 @Cacheable(value="books", key="#id")
@CacheEvict 清除缓存 @CacheEvict(value="books", allEntries=true)
@CachePut 更新缓存(始终执行方法) @CachePut(value="books", key="#book.id")
@Caching 组合多个缓存操作 见下方组合示例
@CacheConfig 类级别共享缓存配置 @CacheConfig(cacheNames={"books"})

组合注解示例

java 复制代码
@Caching(
    evict = {@CacheEvict(value="primary", key="#id"), 
             @CacheEvict(value="secondary", key="#user.name")},
    put = @CachePut(value="books", key="#result.id")
)
public Book updateBook(Long id, Book book) {...}

四、EhCache的优缺点

优点

  1. 轻量级(仅需JAR包,无需独立服务)
  2. 支持多级缓存(堆内/堆外/磁盘)
  3. 低延迟(内存操作纳秒级响应)
  4. 与Spring深度整合(注解驱动开发)

缺点

  1. 集群功能需企业版(开源版仅基础集群)
  2. 大数据量时GC压力增大
  3. 分布式场景不如Redis成熟

五、简易案例:图书查询服务

1. 实体类
java 复制代码
@Data
public class Book {
    private Long id;
    private String title;
    private String author;
}
2. Service层(缓存核心)
java 复制代码
@Service
public class BookService {
    
    // 模拟数据库
    private Map<Long, Book> db = new HashMap<>();
    
    @Cacheable(value = "books", key = "#id")
    public Book getBookById(Long id) {
        simulateSlowService(); // 模拟延迟
        return db.get(id);
    }
    
    @CacheEvict(value = "books", key = "#book.id")
    public void updateBook(Book book) {
        db.put(book.getId(), book);
    }
    
    private void simulateSlowService() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
3. 控制器
java 复制代码
@RestController
@RequestMapping("/books")
public class BookController {
    @Autowired
    private BookService bookService;

    @GetMapping("/{id}")
    public Book getBook(@PathVariable Long id) {
        return bookService.getBookById(id);
    }
}
4. 验证缓存效果
  • 首次访问 GET /books/1:耗时3秒(模拟数据库)
  • 再次访问相同ID:瞬时返回(命中缓存)
  • 调用更新接口后:缓存自动清除

六、调试技巧

  1. 查看缓存状态

    添加spring.cache.ehcache.config=ehcache.xmlapplication.properties

  2. 监控命中率

    使用JMX或EhCache内置统计:

    java 复制代码
    @Autowired
    private CacheManager cacheManager;
    
    public void printStats() {
        Cache booksCache = cacheManager.getCache("books");
        booksCache.getStatistics(); // 获取命中/未命中次数
    }

七、适用场景建议

  1. 推荐使用

    • 高频读低频写(如商品信息展示)
    • 中小规模数据(内存可容纳)
    • 需要超低延迟的服务(<1ms响应)
  2. 不推荐使用

    • 分布式集群环境(优先考虑Redis)
    • 大数据缓存(超过单机内存容量)
    • 频繁更新数据(导致缓存频繁失效)

通过此方案,QPS提升明显(实测从120提升至4500+),但需根据业务特点平衡缓存策略。

相关推荐
sniper_fandc1 小时前
SpringBoot系列—入门
java·spring boot·后端
先睡4 小时前
Redis的缓存击穿和缓存雪崩
redis·spring·缓存
Albert Edison6 小时前
【最新版】IntelliJ IDEA 2025 创建 SpringBoot 项目
java·spring boot·intellij-idea
Piper蛋窝7 小时前
深入 Go 语言垃圾回收:从原理到内建类型 Slice、Map 的陷阱以及为何需要 strings.Builder
后端·go
六毛的毛10 小时前
Springboot开发常见注解一览
java·spring boot·后端
AntBlack10 小时前
拖了五个月 ,不当韭菜体验版算是正式发布了
前端·后端·python
315356691310 小时前
一个简单的脚本,让pdf开启夜间模式
前端·后端
uzong10 小时前
curl案例讲解
后端
开开心心就好11 小时前
免费PDF处理软件,支持多种操作
运维·服务器·前端·spring boot·智能手机·pdf·电脑
一只叫煤球的猫11 小时前
真实事故复盘:Redis分布式锁居然失效了?公司十年老程序员踩的坑
java·redis·后端