Play 框架初探之缓存
Play 提供两种缓存方式:
JVM 内存缓存
使用Memcached 缓存
Play 的CacheImpl 接口( 不知道为什么如此命名) 中提供了safeDelete ,safeAdd ,incr,decr 等高级操作接口,但是两种机制内部实现却大有区别。
方式一基于JVM 内存的缓存方案通过重度封装Ehcache 来做内存缓存,Ehcache 的优点之一是引用非常简单。尽管Cache 是线程安全的,但是是对于set 和get 操作没有内置的timeout 接口,对于incr 和decr 操作需要手动处理并发,总的来说还是需要外层封装代码做不少工作。
// 实现increase需要手动处理并发 public synchronized long incr(String key, int by) { Element e = cache.get(key); if (e == null) { return -1; } long newValue = ((Number) e.getValue()).longValue() + by; Element newE = new Element(key, newValue); newE.setTimeToLive(e.getTimeToLive()); cache.put(newE); return newValue; }
方式二使用Memcached 作为缓存实现,轻度封装了spyMemcached 来连接Memcached, 。spyMemcached 的初始化比较繁琐,但是其使用nio 和concurrent 包的一些机制,存取速度比同类的客户端要快。最重要的一点是spyMemcached 提供了丰富的操作接口,Play 不需要做额外的并发控制处理。
// 客户端提供了increase接口 public long incr(String key, int by) { return client.incr(key, by, 0); } // 异步的safeAdd public boolean safeAdd(String key, Object value, int expiration) { Future<Boolean> future = client.add(key, expiration, value, tc); try { return future.get(1, TimeUnit.SECONDS); } catch (Exception e) { future.cancel(false); } return false; }
总的来说,Play的缓存机制非常简单,选用了存取速度快但是稳定性欠妥的spyMemcached作为Memcached客户端,所以轻量、敏捷是Play所注重的