Rails 关于 cahce 的种种问题,请教大家

6233843 · 2014年05月26日 · 最后由 6233843 回复于 2014年05月26日 · 2679 次阅读

Hi,大家好 最近看到了两篇质量很高的 cache 文章,其中有不少精彩的评论,看完之后我却有一些自己实践中的问题,不搞清楚的话有点难受,请大家把我当新手对待。同时也期待大家多用使用测试结果说话,我也会做做实验贴上答案。

1. 对于静态资源文件,需要 nginx 把资源文件变成文件 cache 么?

root /var/www/current/public;
location ~* ^(/assets|/favicon.ico|images|javascripts|stylesheets|img) {
  log_not_found     off;
  access_log        off;
  expires           max;
}

上述配置会直接让 nginx 读取资源文件返回,并且结合 assets pipeline 的后缀我们可以让它永不过期。可目前 nginx 自己是可以进行 cache 的,比如 memcached 或者 file system,那么我还需要将 nginx 读取文件系统切换成 nginx 读取文件 cache 么?我猜想切换成 ngxin 读取 memcached 肯定效果会好。文章见此

2. 大家使用 last modified 还是 etag? 我读了文章 1文章 2,没有发现推荐一定使用哪一个。所以我想问问大家倾向于哪一个方案,有什么优缺点?

3. Rack::ETag 到底有用没用? 根据Rack::ETag的定义,他会给没有 last-modified or etag 的 response 补上 etag,我觉得挺有用的呀,为什么有人说可以删除,在什么情况下会没有用呢?

4. conditional get 还是 action cache, fragment cache?

def show
    @component = Component.find(params[:id])
    if stale? etag: @component
      render some_page
    end
  end

上面的代码是 conditional_get,我的理解是系统不会再次 render,而直接返回 http code 是 304,内容是空的 response。需要付出的是为了得到 etag 或者 last_modified 的 key 而查询数据库,以及比较 etag 的计算。

另一种方案

<% cache @component do %>
...
<% end %>

如果使用 fragment cache 的 view,而使用 action cache 的配置更简单,直接caches_action :index。如果是 fragment cache,我们需要付出的和 conditional get 一样,只是 rails 会返回 200 带内容的 response,而对 action cache 而言,需要当 cache 资源发生变化时,调用 expire_action 失效之前所 cache 的内容。 与 conditional get 相比,假设都需要从数据库查询一次来判定是否过期,返回 304 和返回 200 带内容失效差不多的情况下,200 带内容总会比 304 慢,因为 304 传输没有内容。我这样理解对么?我是否忽略了其他的因素对传输带来的影响?大家都是怎么使用 conditional get, fragment cache 呢?(我猜测 action cache 用的人不多)

5.我们是否能把从浏览器发送 request 到收到 response 过程中和 cache 相关的动作整理出来? 包括 nginx 端和 unicorn 端,具体粒度还没有想好,但最起码大体概念应该保证大家统一。这个东西我会持续更新,欢迎大家多提意见。

  1. 不需要,静态文件的话,文件系统的效率也很高的;
  2. 我用 ETag 主要是将查询结果加一起算,时间那个感觉不好处理(或许是我理解不够)
  3. 有用,看 Ruby China,开启 Chrome 检查器,看请求状态码;
  4. 你的问题是什么?
  5. 没太明白你意思

#1 楼 @huacnlee

  1. 我将 conditional get 和 fragment cache, action cache 的行为描述出来,不知是否准确。顺便问问大家的使用策略 5.我准备整理一下从 request 到 response 过程中和 cache 相关的动作,比如 db cache,etag cache 之类的
需要 登录 后方可回复, 如果你还没有账号请 注册新账号