Play framework 1.2.3 使用缓存、Memcached集成

2024-06-20 03:18

本文主要是介绍Play framework 1.2.3 使用缓存、Memcached集成,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • play框架包含一个缓存lib,这个lib是用来和Memcached集成做分布式缓存用的。 

如果不配置Memcached,play框架将会使用单独的缓存(EhCache),其数据存储在JVM的堆中。把数据存储在JVM的堆中 违反了play框架“不共享任何东西”的原则,这也导致了你不能把应用程序同时部署到多个机器,即不能在多个机器上负载均衡以保证应用的可用性、高性能(即使在多个机器部署了相同的应用,但是由于不同机器的JVM是相互独立的,会导致不同机器的缓存数据不同,即不同机器对同一请求的响应可能不同!不一致性!) 

理解缓存的应用环境是很重要的:当你把数据放到缓存中, 你不能期望数据在缓存中一直存在。实际上,你不应该这样想。缓存中存取数据很快,但是缓存是有有效期的、并且缓存数据是存放在内存中(并没有做持久化备份)。 

因此最佳使用缓存的方式是当发现缓存的数据不存在时,直接从数据源重新抓取。 
Java代码   收藏代码
  1. public static void allProducts() {  
  2.     List<Product> products = Cache.get("products", List.class);  
  3.     if(products == null) {  
  4.         products = Product.findAll();  
  5.         Cache.set("products", products, "30mn");  
  6.     }  
  7.     render(products);  
  8. }  

缓存API: 
play框架中的缓存类 play.cache.Cache,其包含了从缓存中取值,设值,替换值的方法。 
例子: 
Java代码   收藏代码
  1. public static void showProduct(String id) {  
  2.     Product product = Cache.get("product_" + id, Product.class);  
  3.     if(product == null) {  
  4.         product = Product.findById(id);  
  5.         Cache.set("product_" + id, product, "30mn");  
  6.     }  
  7.     render(product);  
  8. }  
  9.    
  10. public static void addProduct(String name, int price) {  
  11.     Product product = new Product(name, price);  
  12.     product.save();  
  13.     showProduct(product.id);  
  14. }  
  15.    
  16. public static void editProduct(String id, String name, int price) {  
  17.     Product product = Product.findById(id);  
  18.     product.name = name;  
  19.     product.price = price;  
  20.     Cache.set("product_" + id, product, "30mn");  
  21.     showProduct(id);  
  22. }  
  23.    
  24. public static void deleteProduct(String id) {  
  25.     Product product = Product.findById(id);  
  26.     product.delete();  
  27.     Cache.delete("product_" + id);  
  28.     allProducts();  
  29. }  

上面的delete, set等标准方法都是 非阻塞的。也就是说,当你调用 
Java代码   收藏代码
  1. Cache.delete("product_" + id);  

时,delete方法不等缓存对象真的被删除就直接返回。所以,如果在删除缓存对象时发生错误(譬如IO错误),那么缓存对象是仍然存在的。 
sateDelete方法: 阻塞的,在缓存对象真的被删除后,方法才会返回,方法有bool型的返回值来表明操作是否成功。 

注意: 
  • 由于是阻塞方法,使用safe前缀的方法会降低应用的响应速度。因此,只在需要时才那么使用。
  • 当指定参数expiration == "0s"(0秒)时,缓存实际的失效时间可能由于不同的缓存实现相差很大。

不要把Session当缓存使用! 
当你用过基于内存Session实现的框架的话、如Servlet中的HTTP  Session( play框架中的session是以Cookie形式存储在客户端的),你可能会对play框架中只允许在session中以String的形式存储少量数据感到不习惯。在play框架中,session并不是你存储应用数据的地方。 

基于内存的Session,使用例子: 
Java代码   收藏代码
  1. httpServletRequest.getSession().put("userProducts", products);  
  2. ...  
  3. // and then in subsequent requests  
  4. products = (List<Product>)httpServletRequest.getSession().get("use  
  5. rProducts");  

play框架等效实现: 
Java代码   收藏代码
  1. Cache.set(session.getId(), products);  
  2. ...  
  3. // and then in subsequent requests  
  4. List<Product> products = Cache.get(session.getId(), List.class)  

这里我们使用唯一的UUID来作为每个用户缓存的key。注意:和session不同的是, 缓存并不会绑定到任何一个用户中,缓存在整个应用中是共享的。 

集成Memcached缓存配置(application.conf文件): 
memcached:时候启用Memcached缓存,如果不配置,那么play默认使用单独的缓存EhCache,其数据存储在JVM的堆中。可能值:disabled(默认),enabled 

memcached.host:启用Memcached时,指定memcached host地址,默认值:127.0.0.1:11211。 
memcached.host=127.0.0.1:11211 
多个host做分布式缓存时,如下配置: 
memcached.1.host=127.0.0.1:11211 
memcached.2.host=127.0.0.1:11212 



Unmi 注: EhCachePlugin 的注册方式可以查看 play_x.x.x.jar(比如 $PLAY_HOME/repository/local/play/play_2.9.1/2.0.4/jars/play_2.9.1.jar) 包中的 play.plugins 中的内容:

1
2
3
4
5
6
7
8
100:play.api.i18n.MessagesPlugin
200:play.api.db.BoneCPPlugin
300:play.db.ebean.EbeanPlugin
400:play.db.jpa.JPAPlugin
500:play.api.db.evolutions.EvolutionsPlugin
600:play.api.cache.EhCachePlugin
1000:play.api.libs.concurrent.AkkaPlugin
10000:play.api.GlobalPlugin

这是 Play2.0.4 默认注册的插件,其中就包含了 600:play.api.cache.EhCachePlugin 插件。

使用下面简单的 API,你就可以往缓存中存数据了:

1
Cache.set( "item.key" , connectedUser)

之后获取它:

1
val maybeUser : Option[User]  = Cache.getAs[User]( "item.key" )
本文原始链接 http://unmi.cc/play2-0-tutorials-cn-cache-api/, 来自 隔叶黄莺 Unmi Blog

当缓存数据不存在时,还有一个帮助方法在你获取或设置缓存数据给你带来了便利:

1
2
3
val user : User  = Cache.getOrElseAs[User]( "item.key" ) {
   User.findById(connectedUser)
}

缓存 HTTP 响应数据

你可以用标准的 Action 组合简单的创建一个聪明的具体缓存特性的 Action.

注: Play HTTP Result 实例可安全的被缓存并被重用.

Play 提供了默认, 内建的方式来应对标准的情况:

1
2
3
4
5
def index  = Cached( "homePage" ) {
   Action {
     Ok( "Hello world" )
   }
}

或者甚至是这样:

1
2
3
4
5
6
7
def userProfile  = Authenticated { user  = >
   Cached(req  = "profile." + user) {     
     Action {
       Ok(views.html.profile(User.find(user)))
     }  
   }
}

这篇关于Play framework 1.2.3 使用缓存、Memcached集成的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1076950

相关文章

Debezium 与 Apache Kafka 的集成方式步骤详解

《Debezium与ApacheKafka的集成方式步骤详解》本文详细介绍了如何将Debezium与ApacheKafka集成,包括集成概述、步骤、注意事项等,通过KafkaConnect,D... 目录一、集成概述二、集成步骤1. 准备 Kafka 环境2. 配置 Kafka Connect3. 安装 D

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

Spring AI集成DeepSeek的详细步骤

《SpringAI集成DeepSeek的详细步骤》DeepSeek作为一款卓越的国产AI模型,越来越多的公司考虑在自己的应用中集成,对于Java应用来说,我们可以借助SpringAI集成DeepSe... 目录DeepSeek 介绍Spring AI 是什么?1、环境准备2、构建项目2.1、pom依赖2.2

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

在 Spring Boot 中使用 @Autowired和 @Bean注解的示例详解

《在SpringBoot中使用@Autowired和@Bean注解的示例详解》本文通过一个示例演示了如何在SpringBoot中使用@Autowired和@Bean注解进行依赖注入和Bean... 目录在 Spring Boot 中使用 @Autowired 和 @Bean 注解示例背景1. 定义 Stud

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景

使用Python快速实现链接转word文档

《使用Python快速实现链接转word文档》这篇文章主要为大家详细介绍了如何使用Python快速实现链接转word文档功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 演示代码展示from newspaper import Articlefrom docx import

oracle DBMS_SQL.PARSE的使用方法和示例

《oracleDBMS_SQL.PARSE的使用方法和示例》DBMS_SQL是Oracle数据库中的一个强大包,用于动态构建和执行SQL语句,DBMS_SQL.PARSE过程解析SQL语句或PL/S... 目录语法示例注意事项DBMS_SQL 是 oracle 数据库中的一个强大包,它允许动态地构建和执行