Use a cache
To create high-performance systems, sometimes you need to cache data. Play has a cache library and will use Memcached when used in a distributed environment.
If you don’t configure Memcached, Play will use a standalone cache that stores data in the JVM heap. Caching data in the JVM application breaks the “share nothing” assumption made by Play: you can’t run your application on several servers, and expect the application to behave consistently. Each application instance will have a different copy of the data.
It is important to understand that the cache contract is clear: when you put data in a cache, you can’t expect that data to remain there forever. In fact you shouldn’t. A cache is fast, but values expire, and the cache generally exists only in memory (without persistent backup).
So the best way to use the cache is to repopulate it when it doesn’t have what you expect:
public static void allProducts() {
List<Product> products = Cache.get("products", List.class);
if(products == null) {
products = Product.findAll();
Cache.set("products", products, "30mn");
}
render(products);
}
The cache API
The cache API is provided by the play.cache.Cache class. This class contains the set of methods to set, replace, and get data from the cache. Refer to the Memcached documentation to understand the exact behavior of each method.
Some examples:
public static void showProduct(String id) {
Product product = Cache.get("product_" + id, Product.class);
if(product == null) {
product = Product.findById(id);
Cache.set("product_" + id, product, "30mn");
}
render(product);
}
public static void addProduct(String name, int price) {
Product product = new Product(name, price);
product.save();
showProduct(id);
}
public static void editProduct(String id, String name, int price) {
Product product = Product.findById(id);
product.name = name;
product.price = price;
Cache.set("product_" + id, product, "30mn");
showProduct(id);
}
public static void deleteProduct(String id) {
Product product = Product.findById(id);
product.delete();
Cache.delete("product_" + id);
allProducts();
}
Some methods start with the safe prefix – e.g. safeDelete, safeSet. The standard methods are non-blocking. That means that when you issue the call:
Cache.delete("product_" + id);
The delete method will return immediately and will not wait until the cached object is actually deleted. So if an error occurs – e.g. an IO error – the object may still be present.
When you need to make sure that the object is deleted before continuing, you can use the safeDeletemethod:
Cache.safeDelete("product_" + id);
This method is blocking and returns a boolean value indicating whether the object has been deleted or not. So the full pattern that ensures an item is deleted from the cache is:
if(!Cache.safeDelete("product_" + id)) {
throw new Exception("Oops, the product has not been removed from the cache");
}
...
Note that those being blocking calls, safe methods will slow down your application. So use them only when needed.
Don’t use the Session as a cache!
If you come from a framework that uses an in-memory Session implementation, you may be frustrated to see that Play allows only a small set of String data to be saved in the HTTP Session. But this is much better because a session is not the place to cache your application data!
So if you have been accustomed to doing things similar to:
httpServletRequest.getSession().put("userProducts", products);
...
// and then in subsequent requests
products = (List<Product>)httpServletRequest.getSession().get("userProducts");
In Play you achieve the same effect a little differently. We think it’s a better approach:
Cache.set(session.getId(), products);
...
// and then in subsequent requests
List<Product> products = Cache.get(session.getId(), List.class)
Here we have used a unique UUID to keep unique information in the Cache for each user. Remember that, unlike a session object, the cache is not bound to any particular User!
Configure memcached
When you want to enable a real Memcached implementation, enable Memcached and define the daemon address in your application.conf:
memcached=enabled
memcached.host=127.0.0.1:11211
You can connect to a distributed cache by specifying multiple daemon addresses:
memcached=enabled
memcached.1.host=127.0.0.1:11211
memcached.2.host=127.0.0.1:11212
Continuing the discussion
Learn about Sending emails.
Use a cache的更多相关文章
- ASP.NET Core 折腾笔记二:自己写个完整的Cache缓存类来支持.NET Core
背景: 1:.NET Core 已经没System.Web,也木有了HttpRuntime.Cache,因此,该空间下Cache也木有了. 2:.NET Core 有新的Memory Cache提供, ...
- [Java 缓存] Java Cache之 DCache的简单应用.
前言 上次总结了下本地缓存Guava Cache的简单应用, 这次来继续说下项目中使用的DCache的简单使用. 这里分为几部分进行总结, 1)DCache介绍; 2)DCache配置及使用; 3)使 ...
- Spring cache简单使用guava cache
Spring cache简单使用 前言 spring有一套和各种缓存的集成方式.类似于sl4j,你可以选择log框架实现,也一样可以实现缓存实现,比如ehcache,guava cache. [TOC ...
- 笔记:Memory Notification: Library Cache Object loaded into SGA
笔记:Memory Notification: Library Cache Object loaded into SGA在警告日志中发现一些这样的警告信息:Mon Nov 21 14:24:22 20 ...
- ABP源码分析十三:缓存Cache实现
ABP中有两种cache的实现方式:MemroyCache 和 RedisCache. 如下图,两者都继承至ICache接口(准确说是CacheBase抽象类).ABP核心模块封装了MemroyCac ...
- [Java 缓存] Java Cache之 Guava Cache的简单应用.
前言 今天第一次使用MarkDown的形式发博客. 准备记录一下自己对Guava Cache的认识及项目中的实际使用经验. 一: 什么是Guava Guava工程包含了若干被Google的 Java项 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(40)-精准在线人数统计实现-【过滤器+Cache】
系列目录 上次的探讨没有任何结果,我浏览了大量的文章和个别系统的参考!决定用Cache来做,这可能有点难以接受但是配合mvc过滤器来做效果非常好! 由于之前的过滤器我们用过了OnActionExecu ...
- HTML5离线缓存(Application Cache)
HTML5离线缓存又名Application Cache,是从浏览器的缓存中分出来的一块缓存区,要想在这个缓存中保存数据,可以使用一个描述文件(manifest file),列出要下载和缓存的资源. ...
- 第三篇 Entity Framework Plus 之 Query Cache
离上一篇博客,快一周,工作太忙,只能利用休息日来写一些跟大家分享,Entity Framework Plus 组件系列文章,之前已经写过两篇 第一篇 Entity Framework Plus 之 A ...
- HTML5应用程序缓存Application Cache
什么是Application Cache HTML5引入了应用程序缓存技术,意味着web应用可进行缓存,并在没有网络的情况下使用,通过创建cache manifest文件,可以轻松的创建离线应用. A ...
随机推荐
- 快速入门系列--WebAPI--04在老版本MVC4下的调整
WebAPI是建立在MVC和WCF的基础上的,原来微软老是喜欢封装的很多,这次终于愿意将http编程模型的相关细节暴露给我们了.在之前的介绍中,基本上都基于.NET 4.5之后版本,其System.N ...
- KlayGE 4.4中渲染的改进(一):只需要SM3的TBDR
转载请注明出处为KlayGE游戏引擎,本文的永久链接为http://www.klayge.org/?p=2736 KlayGE从4.0开始引入deferred rendering层(DR),并且这几个 ...
- Android线程机制——AsyncTask
对于Android为什么要使用多线程,因为从Android4.0之后,谷歌规定了网络操作不允许放在主线程中执行,由此就有了多线程的机制,有个JAVA学习经验的朋友一定知道多线程指的是什么,简单来讲就是 ...
- 如何利用Direct NFS克隆数据库
CloneDB是Oracle 11.2.0.3推出的一项新特性,它利用的了11g新引入的Direct NFS.它直接利用目标数据库的备份,无需将备份COPY到克隆环境下,使得一个备份可以克隆多个不同用 ...
- Android强制设定横屏时,SurfaceView一直黑屏
接着上一个问题,解决了SurfaceView闪屏问题之后(http://www.cnblogs.com/Joanna-Yan/p/4829325.html),又有了一个新的问题.现在我想设置含有fra ...
- REST API出错响应的设计
REST API应用很多,一方面提供公共API的平台越来越多,比如微博.微信等:一方面移动应用盛行,为Web端.Android端.IOS端.PC端,搭建一个统一的后台,以REST API的形式提供服务 ...
- ASP.NET 网站从Sever2003迁移到Sever 2008部署后不能访问
最近公司运维迁移网站遇到部署后始终不能访问,一直提示无法访问请求的页面,但是请求页面正常,程序没问题,在本地电脑运行正常,运维找了好久没找到原因. 后来问我,我也找了好久,最后终于解决了. 解决方法是 ...
- nodejs学习笔记三——nodejs使用富文本插件ueditor
在做自己的nodejs项目的时候遇到需要使用ueditor.原来下载的是ueditor的jsp版本.目录如下 在ueditor.config.js中有配置服务器home路径(这个home路径能找到u ...
- 【Swift学习】Swift编程之旅---继承(十七)
在 Swift 中,继承是区分「类」与其它类型的一个基本特征.swift不支持多重继承.类可以调用和访问超类的方法,属性和subscripts下标,并且可以重写(override)这些方法,属性和附属 ...
- 【转载】关于BooleanQuery在搜索中的用处
我们在搜索中可能会遇到要搜索索引文件中不同字段,不同字段之间就存在了与或非的运算关系,如:这个xx字段中必须存在什么什么关键词,而另一个 XXX字段可以存在或不存在什么什么关键词等等等.这就需要有Bo ...