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

相关文章

Pydantic中Optional 和Union类型的使用

《Pydantic中Optional和Union类型的使用》本文主要介绍了Pydantic中Optional和Union类型的使用,这两者在处理可选字段和多类型字段时尤为重要,文中通过示例代码介绍的... 目录简介Optional 类型Union 类型Optional 和 Union 的组合总结简介Pyd

Vue3使用router,params传参为空问题

《Vue3使用router,params传参为空问题》:本文主要介绍Vue3使用router,params传参为空问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录vue3使用China编程router,params传参为空1.使用query方式传参2.使用 Histo

使用Python自建轻量级的HTTP调试工具

《使用Python自建轻量级的HTTP调试工具》这篇文章主要为大家详细介绍了如何使用Python自建一个轻量级的HTTP调试工具,文中的示例代码讲解详细,感兴趣的小伙伴可以参考一下... 目录一、为什么需要自建工具二、核心功能设计三、技术选型四、分步实现五、进阶优化技巧六、使用示例七、性能对比八、扩展方向建

使用Python实现一键隐藏屏幕并锁定输入

《使用Python实现一键隐藏屏幕并锁定输入》本文主要介绍了使用Python编写一个一键隐藏屏幕并锁定输入的黑科技程序,能够在指定热键触发后立即遮挡屏幕,并禁止一切键盘鼠标输入,这样就再也不用担心自己... 目录1. 概述2. 功能亮点3.代码实现4.使用方法5. 展示效果6. 代码优化与拓展7. 总结1.

使用Python开发一个简单的本地图片服务器

《使用Python开发一个简单的本地图片服务器》本文介绍了如何结合wxPython构建的图形用户界面GUI和Python内建的Web服务器功能,在本地网络中搭建一个私人的,即开即用的网页相册,文中的示... 目录项目目标核心技术栈代码深度解析完整代码工作流程主要功能与优势潜在改进与思考运行结果总结你是否曾经

Linux中的计划任务(crontab)使用方式

《Linux中的计划任务(crontab)使用方式》:本文主要介绍Linux中的计划任务(crontab)使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、前言1、linux的起源与发展2、什么是计划任务(crontab)二、crontab基础1、cro

kotlin中const 和val的区别及使用场景分析

《kotlin中const和val的区别及使用场景分析》在Kotlin中,const和val都是用来声明常量的,但它们的使用场景和功能有所不同,下面给大家介绍kotlin中const和val的区别,... 目录kotlin中const 和val的区别1. val:2. const:二 代码示例1 Java

C++变换迭代器使用方法小结

《C++变换迭代器使用方法小结》本文主要介绍了C++变换迭代器使用方法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1、源码2、代码解析代码解析:transform_iterator1. transform_iterat

C++中std::distance使用方法示例

《C++中std::distance使用方法示例》std::distance是C++标准库中的一个函数,用于计算两个迭代器之间的距离,本文主要介绍了C++中std::distance使用方法示例,具... 目录语法使用方式解释示例输出:其他说明:总结std::distance&n编程bsp;是 C++ 标准

vue使用docxtemplater导出word

《vue使用docxtemplater导出word》docxtemplater是一种邮件合并工具,以编程方式使用并处理条件、循环,并且可以扩展以插入任何内容,下面我们来看看如何使用docxtempl... 目录docxtemplatervue使用docxtemplater导出word安装常用语法 封装导出方