Xitrum学习笔记16 - Server端缓存

Xitrum为快速响应提供了大量的客户端和服务器端缓存。

在web服务层,小文件被缓存在内存中,大文件通过NIO零拷贝被发送。关于零拷贝可参照https://my.oschina.net/plucury/blog/192577

Xitrum的静态文件响应速度类似于Nginx。

在Web框架层,可以以Rails的方式声明page、action和对象缓存。

Google所有的最好的经验例如 条件Get 被应用到客户端缓存。

对于动态内容,如果内容在创建后没有改变(像静态文件一样),可以通过在action中调用setClientCacheAggressively()方法设置头信息让客户端主动缓存。

有时要避免客户端缓存,可以在action中调用setNoClientCache()方法。

缓存页面或action

import xitrum.Action
import xitrum.annotation.{GET, CacheActionMinute, CachePageMinute}
@GET("articles")
@CachePageMinute(1)
class ArticlesIndex extends Action {
  def execute() {
    ...
  }
}
@GET("articles/:id")
@CacheActionMinute(1)
class ArticlesShow extends Action {
  def execute() {
    ...
  }
}

处理请求的顺序: (1) request -> (2) before过滤器方法 -> (3) action的execute方法-> (4) response

对于第一个请求,Xitrum会缓存响应一段指定的时间。@CachePageMinute(1) 和@CacheActionMinute(1) 都表示缓存1分钟。

Xitrum只在响应状态为"200 OK"时缓存响应,其他如“500 Internal Server Error” or “302 Found” (redirect) 不会缓存响应。

以下对相同的action进行的请求,如果响应已缓存的时间还在指定的时间内,Xitrum会响应返回已缓存的响应:

  • 对于page缓存,顺序是 (1)->(4)
  • 对于action缓存,顺序是 (1) -> (2) -> (4), 或者当一个before过滤器返回false时只有 (1) -> (2)

两者区别是,对于page缓存,before过滤器不会运行。

一般地,当相同的响应可以返回给所有的用户时,可以使用page缓存;

            当需要运行before过滤器从而引导到以缓存的响应时,使用action缓存。如检查用户是否已登录,已登录则返回已缓存的响应,没登录则重定向到登录页面。

缓存对象

可以使用xitrum.Config.xitrum.cache里的方法,它是 xitrum.Cache的一个实例。

没有指定TTL(time to live存活时间)时,使用put(key, value)

指定了TTL时,使用putSecond(key, value, seconds),putMinute(key, value, minutes),putHour(key, value, hours),putDay(key, value, days)

只要有缺失,putIfAbsent(key, value),putIfAbsentSecond(key, value, seconds),putIfAbsentMinute(key, value, minutes),putIfAbsentHour(key, value, hours),

putIfAbsentDay(key, value, days)

移除缓存

移除page或action缓存:removeAction[MyAction]

移除对象缓存:remove(key)

移除所有以某前缀开始的key:removePrefix(keyPrefix)

使用removePrefix,可以基于前缀组成一个层级的缓存结构。例如,你要缓存和文章相关的内容,当文章变化时你要删除所有这些内容:

import xitrum.Config.xitrum.cache
// Cache with a prefix
val prefix = "articles/" + article.id
cache.put(prefix + "/likes", likes)
cache.put(prefix + "/comments", comments)
// Later, when something happens and you want to remove all cache related to the article
cache.remove(prefix)

配置

Xitrum中的缓存功能由缓存引擎提供,你可以选择符合需求的引擎。

在config/xitrum.conf中,你可以通过以下两种方式的一种配置缓存引擎,这也取决于所选择的引擎:

cache = my.cache.EngineClassName
#或者:
cache {
  "my.cache.EngineClassName" {
    option1 = value1
    option2 = value2
  }
}

Xitrum默认提供的是

cache {
    # Simple in-memory cache
    "xitrum.local.LruCache" {
      maxElems = 10000
    }
}

如果使用的是一个服务器集群,可以使用 Hazelcast(https://github.com/xitrum-framework/xitrum-hazelcast)。

如果想创建自己的缓存引擎,需要实现 xitrum.Cache类

缓存如何工作

Inbound:

                        the action response
                        should be cached and
request             the cache already exists?
-------------------------+---------------NO--------------->
                                 |
<---------YES----------+
  respond from cache

Outbound:

                        the action response
                        should be cached and
                        the cache does not exist?               response
<---------NO-------------+---------------------------------
                                   |
<---------YES------------+
  store response to cache

xitrum.util.LocalLruCache

以上的缓存可以在整个系统中共享,如果只想要一个小的方便的缓存,可以使用xitrum.util.LocalLruCache

import xitrum.util.LocalLruCache
// LRU (Least Recently Used) cache that can contain 1000 elements.
// Keys and values are both of type String.
val cache = LocalLruCache[String, String](1000)

返回的cache是一个 java.util.LinkedHashMap,可以使用LinkedHashMap的方法

posted @ 2017-05-16 16:19  子秦  阅读(245)  评论(0编辑  收藏  举报