缓存框架之王:EhCache,本地缓存的经典方案

文摘   2024-11-03 18:39   江苏  

点击上蓝字关注我把,加星标★

作为一名Java开发者,我相信大家都遇到过需要提升应用性能的场景。在缓存往往是我们的首选武器。今天,我们就来深入探讨Java世界中的一位“缓存大师”——EhCache。这个强大而灵活的本地缓存解决方案,绝对值得我们好好研究一番。



一、准备工作



在开始我们的EhCache之旅前,让我们先做些准备工作。


1.1 环境要求

  • JDK 8+

  • Maven 3.x 或 Gradle 4.x+

1.2 Maven依赖

在你的pom.xml文件中添加以下依赖:


xml


复制


<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.9.9</version>
</dependency>

1.3 基础概念

在深入EhCache之前,我们需要理解几个核心概念:


  • Cache :缓存,用于存储键值对数据。

  • CacheManager :缓存管理器,负责创建、配置和管理Cache实例。

  • Entry :缓存条目,代表存储在缓存中的单个键值对。


二、基本用法



让我们从一个简单的例子开始,感受EhCache的魅力。


2.1 创建CacheManager

java


复制


import org.ehcache.CacheManager;
import org.ehcache.config.builders.CacheManagerBuilder;

public class EhcacheDemo {
public static void main(String[] args) {
CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder().build();
cacheManager.init();

// 使用完毕后关闭CacheManager
// cacheManager.close();
}
}

2.2 创建和使用Cache

java


复制


import org.ehcache.Cache;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;

public class EhcacheDemo {
public static void main(String[] args) {
CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder().build();
cacheManager.init();

// 创建Cache
Cache<String, String> myCache = cacheManager.createCache(“myCache”,
CacheConfigurationBuilder.newCacheConfigurationBuilder(
String.class, String.class,
ResourcePoolsBuilder.heap(10)));

// 使用Cache
myCache.put(“key1”, “Hello, EhCache!”);
String value = myCache.get(“key1”);
System.out.println(“Value for key1: ” + value);

cacheManager.close();
}
}

在这个例子中,我们创建了一个简单的String键值对缓存,并设置了最大容量为10个元素。



三、进阶用法



EhCache的强大之处在于它的灵活配置和丰富特性。让我们来看看一些进阶用法。


3.1 配置不同的存储层

EhCache支持多种存储层,包括堆内存、堆外内存和磁盘存储。


java


复制


CacheConfiguration<Long, String> cacheConfiguration = CacheConfigurationBuilder
.newCacheConfigurationBuilder(Long.class, String.class,
ResourcePoolsBuilder.newResourcePoolsBuilder()
.heap(10, EntryUnit.ENTRIES)
.offheap(1, MemoryUnit.MB)
.disk(20, MemoryUnit.MB, true))
.withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofSeconds(20)))
.build();

Cache<Long, String> myCache = cacheManager.createCache(“myCache”, cacheConfiguration);

这个配置创建了一个三层存储的缓存,包括堆内存、堆外内存和磁盘存储,并设置了20秒的过期时间。


3.2 使用监听器

EhCache允许我们添加监听器来跟踪缓存的各种事件。


java


复制


CacheEventListenerConfigurationBuilder cacheEventListenerConfiguration = CacheEventListenerConfigurationBuilder
.newEventListenerConfiguration(new CacheEventListener<Long, String>() {
@Override
public void onEvent(CacheEvent<? extends Long, ? extends String> event) {
System.out.println(“Event: ” + event.getType() + “ Key: ” + event.getKey() + “ old value: ” + event.getOldValue() + “ new value: ” + event.getNewValue());
}
}, EventType.CREATED, EventType.UPDATED, EventType.REMOVED, EventType.EXPIRED)
.ordered().synchronous();

CacheConfiguration<Long, String> cacheConfiguration = CacheConfigurationBuilder
.newCacheConfigurationBuilder(Long.class, String.class, ResourcePoolsBuilder.heap(10))
.withService(cacheEventListenerConfiguration)
.build();

Cache<Long, String> myCache = cacheManager.createCache(“myCache”, cacheConfiguration);

这个例子添加了一个监听器,可以监听缓存的创建、更新、删除和过期事件。



四、实际案例



让我们通过两个实际案例来看看EhCache如何在实际项目中发挥作用。


4.1 用户信息缓存

假设我们有一个用户服务,需要频繁查询用户信息。我们可以使用EhCache来缓存用户数据,提高查询效率。


java


复制


public class UserService {
private final Cache<Long, User> userCache;
private final UserDao userDao;

public UserService(CacheManager cacheManager, UserDao userDao) {
this.userCache = cacheManager.createCache(“userCache”,
CacheConfigurationBuilder.newCacheConfigurationBuilder(
Long.class, User.class,
ResourcePoolsBuilder.heap(1000))
.withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofMinutes(30)))
.build());
this.userDao = userDao;
}

public User getUser(Long userId) {
return userCache.get(userId, key -> userDao.getUserById(key));
}

public void updateUser(User user) {
userDao.updateUser(user);
userCache.put(user.getId(), user);
}
}

在这个例子中,我们创建了一个用户缓存,最多存储1000个用户信息,过期时间为30分钟。getUser方法首先尝试从缓存获取用户信息,如果缓存未命中,则从数据库加载并放入缓存。


4.2 商品库存缓存

在电商系统中,商品库存是一个频繁访问的数据。我们可以使用EhCache来缓存库存信息,提高系统响应速度。


java


复制


public class InventoryService {
private final Cache<Long, Integer> inventoryCache;
private final InventoryDao inventoryDao;

public InventoryService(CacheManager cacheManager, InventoryDao inventoryDao) {
this.inventoryCache = cacheManager.createCache(“inventoryCache”,
CacheConfigurationBuilder.newCacheConfigurationBuilder(
Long.class, Integer.class,
ResourcePoolsBuilder.newResourcePoolsBuilder()
.heap(10000, EntryUnit.ENTRIES)
.offheap(10, MemoryUnit.MB))
.withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofMinutes(5)))
.build());
this.inventoryDao = inventoryDao;
}

public int getInventory(Long productId) {
return inventoryCache.get(productId, key -> inventoryDao.getInventory(key));
}

public void updateInventory(Long productId, int newInventory) {
inventoryDao.updateInventory(productId, newInventory);
inventoryCache.put(productId, newInventory);
}
}

这个例子中,我们创建了一个商品库存缓存,使用了堆内存和堆外内存,可以存储大量商品的库存信息。缓存的过期时间设置为5分钟,以平衡数据实时性和系统性能。



五、总结



EhCache作为一个成熟的本地缓存解决方案,为我们提供了强大的缓存能力和灵活的配置选项。它的核心优势包括:


  1. 多层存储支持,可以根据需求选择合适的存储方式。

  2. 丰富的配置选项,包括过期策略、容量控制等。

  3. 良好的性能和可靠性,经过多年生产环境的检验。

  4. 易于集成,可以seamlessly融入到现有的Java项目中。

在实际开发中,我建议大家根据项目的具体需求来选择和配置EhCache。也要注意以下几点:


  • 合理设置缓存容量和过期时间,避免缓存占用过多资源。

  • 在分布式环境中,需要考虑缓存一致性问题,可能需要结合其他技术如分布式缓存。

  • 定期监控缓存的命中率和使用情况,及时调整配置以优化性能。

本文介绍了EhCache的核心特性和实践应用。在实际开发中,建议读者结合项目需求选择合适的特性,同时关注官方文档获取最新更新。如有问题,欢迎在评论区交流讨论。祝各位开发愉快!


点个在看你最好看




福爷老金说
关注我了解更多养老金动态~
 最新文章