Play framework 1.2.3 使用缓存、Memcached集成

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

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

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

因此最佳使用缓存的方式是当发现缓存的数据不存在时,直接从数据源重新抓取。
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);
}

[b]缓存API:[/b]
play框架中的缓存类[color=red]play.cache.Cache[/color],其包含了从缓存中取值,设值,替换值的方法。
例子:
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(product.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();
}

上面的delete, set等标准方法都是[color=red]非阻塞的[/color]。也就是说,当你调用
Cache.delete("product_" + id);

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

[b]注意:[/b]
[list]
[*]由于是阻塞方法,使用safe前缀的方法会降低应用的响应速度。因此,只在需要时才那么使用。
[*]当指定参数expiration == "0s"(0秒)时,缓存实际的失效时间可能由于不同的缓存实现相差很大。
[/list]
[b]不要把Session当缓存使用![/b]
当你用过基于内存Session实现的框架的话、如Servlet中的HTTP Session([color=red]play框架中的session是以Cookie形式存储在客户端的[/color]),你可能会对play框架中只允许在session中以String的形式存储少量数据感到不习惯。在play框架中,session并不是你存储应用数据的地方。

基于内存的Session,使用例子:
httpServletRequest.getSession().put("userProducts", products);
...
// and then in subsequent requests
products = (List<Product>)httpServletRequest.getSession().get("use
rProducts");

play框架等效实现:
Cache.set(session.getId(), products);
...
// and then in subsequent requests
List<Product> products = Cache.get(session.getId(), List.class)

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

[b]集成Memcached缓存配置(application.conf文件)[/b]:
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

参考:[url=http://www.playframework.org/documentation/1.2.3/cache]Use a cache[/url]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值