缓存最佳实践java



我有一个基于Struts的B2B应用程序。一个页面中可以有20-25个列表框,列表框中的数据可能因客户而异。例如,列表框将是合格国家/地区列表、产品品牌列表等。一个客户下将有多个用户。在当前的解决方案中,客户对象是在客户下的第一个用户登录时在应用程序范围(ServletContext)中设置的。采取这种方法是为了避免在页面加载时调用数据库。

我们正在寻求重新构建解决方案,预计客户群将增长50%。新的应用程序将在带有Hibernate JPA的Spring框架上,最后该应用程序将部署在JBoss集群上。正在寻找处理列表框数据的最佳缓存方法的专家意见。

谢谢。

如果您的应用程序正在使用Spring,那么缓存抽象是一个良好的开端,请参阅本文以获得的良好介绍

设计您的模型

您需要为这些列表的内容设计一个模型,您可能会在struts应用程序中直接重用这些列表。您可能不想缓存Country本身,而是更多地缓存过滤列表,因为这可能是您获得最佳收益的地方。由于您的应用程序正在使用Hibernate,因此您可以很容易地为实体启用Hibernate中的二级缓存。

一旦你设计好了,你就需要找到一种方法来生成一个足够好的密钥来识别你的应用程序的用户。可能客户的id是一个很好的候选者。

创建存储库

然后,您可以创建一个存储库,根据一些参数提供这些列表的内容。理想情况下,唯一的论据是识别客户的钥匙,但你可以根据自己的需求进行调整。例如:

public class YourRepositoryImpl implements YourRepository {
@Cacheable("modelCache")
public YourModel get(String customerId) {
// compute the list for that customer. 
// Only called if not in the cache
}
...
}

这基本上指示Spring使用get方法的结果更新modelCache缓存。在这种特殊情况下,customerId是用于在高速缓存中存储值的密钥。通常,如果再次调用此方法,代码甚至不会被调用,因为Spring会在缓存中找到该键的条目,并直接返回值。

如果无法轻松创建密钥,或者需要更多上下文,则可以定义自定义KeyGenerator或指定要直接在注释中用作SPeL表达式的模式。

启用缓存支持

您可以通过@EnableCachingjava配置的XML命名空间轻松打开缓存支持。实际的缓存被委托给一个缓存实现,该实现支持ehcache、guava、并发哈希映射和JSR-107兼容的开箱即用缓存。在这个阶段,你可以配置你想要的所有缓存提供商特定的设置:它不会影响你的代码,你甚至可以在不更改代码的情况下从一个提供商更改到另一个提供商

正在更新缓存

如果数据是只读的,那就差不多了。如果这些列表的内容发生了变化,您需要处理驱逐,以便再次调用get方法来重新计算/刷新列表(请参阅@CacheEvict),或者您可以自己更新缓存的内容(请参阅CachePut)。您还需要配置后端缓存,以便缓存的内容在集群的所有节点上保持一致。

要求特定列表已更改的逻辑可能很难实现,因此在设计模型时,您可能应该尽早关注这一部分。

最新更新