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

相关文章

使用Python和OpenCV库实现实时颜色识别系统

《使用Python和OpenCV库实现实时颜色识别系统》:本文主要介绍使用Python和OpenCV库实现的实时颜色识别系统,这个系统能够通过摄像头捕捉视频流,并在视频中指定区域内识别主要颜色(红... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间详解

Windows下C++使用SQLitede的操作过程

《Windows下C++使用SQLitede的操作过程》本文介绍了Windows下C++使用SQLite的安装配置、CppSQLite库封装优势、核心功能(如数据库连接、事务管理)、跨平台支持及性能优... 目录Windows下C++使用SQLite1、安装2、代码示例CppSQLite:C++轻松操作SQ

Python常用命令提示符使用方法详解

《Python常用命令提示符使用方法详解》在学习python的过程中,我们需要用到命令提示符(CMD)进行环境的配置,:本文主要介绍Python常用命令提示符使用方法的相关资料,文中通过代码介绍的... 目录一、python环境基础命令【Windows】1、检查Python是否安装2、 查看Python的安

Python并行处理实战之如何使用ProcessPoolExecutor加速计算

《Python并行处理实战之如何使用ProcessPoolExecutor加速计算》Python提供了多种并行处理的方式,其中concurrent.futures模块的ProcessPoolExecu... 目录简介完整代码示例代码解释1. 导入必要的模块2. 定义处理函数3. 主函数4. 生成数字列表5.

Python中help()和dir()函数的使用

《Python中help()和dir()函数的使用》我们经常需要查看某个对象(如模块、类、函数等)的属性和方法,Python提供了两个内置函数help()和dir(),它们可以帮助我们快速了解代... 目录1. 引言2. help() 函数2.1 作用2.2 使用方法2.3 示例(1) 查看内置函数的帮助(

Linux脚本(shell)的使用方式

《Linux脚本(shell)的使用方式》:本文主要介绍Linux脚本(shell)的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录概述语法详解数学运算表达式Shell变量变量分类环境变量Shell内部变量自定义变量:定义、赋值自定义变量:引用、修改、删

Java使用HttpClient实现图片下载与本地保存功能

《Java使用HttpClient实现图片下载与本地保存功能》在当今数字化时代,网络资源的获取与处理已成为软件开发中的常见需求,其中,图片作为网络上最常见的资源之一,其下载与保存功能在许多应用场景中都... 目录引言一、Apache HttpClient简介二、技术栈与环境准备三、实现图片下载与保存功能1.

Python中使用uv创建环境及原理举例详解

《Python中使用uv创建环境及原理举例详解》uv是Astral团队开发的高性能Python工具,整合包管理、虚拟环境、Python版本控制等功能,:本文主要介绍Python中使用uv创建环境及... 目录一、uv工具简介核心特点:二、安装uv1. 通过pip安装2. 通过脚本安装验证安装:配置镜像源(可

LiteFlow轻量级工作流引擎使用示例详解

《LiteFlow轻量级工作流引擎使用示例详解》:本文主要介绍LiteFlow是一个灵活、简洁且轻量的工作流引擎,适合用于中小型项目和微服务架构中的流程编排,本文给大家介绍LiteFlow轻量级工... 目录1. LiteFlow 主要特点2. 工作流定义方式3. LiteFlow 流程示例4. LiteF

使用Python开发一个现代化屏幕取色器

《使用Python开发一个现代化屏幕取色器》在UI设计、网页开发等场景中,颜色拾取是高频需求,:本文主要介绍如何使用Python开发一个现代化屏幕取色器,有需要的小伙伴可以参考一下... 目录一、项目概述二、核心功能解析2.1 实时颜色追踪2.2 智能颜色显示三、效果展示四、实现步骤详解4.1 环境配置4.