2012-03-02 48 views
4

在一个旧的Rails项目页面缓存工作正如我在网上阅读doc所期望的那样,在Rails 3.1/3.2中,它的工作方式并不一样。看起来Rails将页面写入磁盘,但从不使用它们(所以我认为它将内存中的页面缓存)。Rails 3.2何时使用它缓存到磁盘的页面?

(请忍受我长的解释,这并不复杂只是彻底...)

在一个新的Rails 3.2.2应用程序,我有以下几点:

class HomeController < ApplicationController 
    caches_page :index 
    def index 
    expires_in 1.year, :private => false, :public => true 
    end 
end 

当我开始我的服务器在生产和访问本地主机我看到:

cache: [GET /] miss, store 


Started GET "/" for 127.0.0.1 at 2012-03-02 12:19:22 -0500 
Processing by HomeController#index as HTML 
    Rendered home/index.html.erb within layouts/application (20.0ms) 
Write page /home/sheldon/Dev/rails-3.2-app/public/index.html (0.4ms) 
Completed 200 OK in 30ms (Views: 28.7ms | ActiveRecord: 0.0ms) 

文件public/index.html出现在磁盘上。

我使用的是Firefox,如果我按Ctrl + R或SHIFT + CTRL + R我看到:

cache: [GET /] fresh 
[2012-03-02 12:21:39] WARN Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true 

如果我编辑公共/ index.html的文件直接,然后按Ctrl + R或Ctrl + shift + r我没有看到我对该文件所做的更改。

如果我打开一个轨道控制台,然后输入Rails.cache.clear我看到:

=> ["/home/sheldon/Dev/rails-3.2-app/tmp/cache/9F4", "/home/sheldon/Dev/rails-3.2-app/tmp/cache/A9A"] 

现在,如果我按Ctrl + R或CTRL + SHIFT + R我看到:

cache: [GET /] miss, store 


Started GET "/" for 127.0.0.1 at 2012-03-02 12:37:04 -0500 
Processing by HomeController#index as HTML 
    Rendered home/index.html.erb within layouts/application (0.0ms) 
Write page /home/sheldon/Dev/rails-3.2-app/public/index.html (0.3ms) 
Completed 200 OK in 2ms (Views: 1.2ms | ActiveRecord: 0.0ms) 

而我的公共变化/index.html被覆盖。

因此看起来public/index.html从来没有使用过。

如果我编辑tmp/cache(在上面的控制台输出)中找到的html文件,然后ctrl + r或ctrl + shift + r,我仍然看不到直接对tmp/cache文件所做的更改。

如果我设置config.cache_store = :file_store, Rails.public_path + "/cache"的行为似乎是相同的。

入门指南Rails指出:“Rails将在公共目录中提供任何静态文件,优先于我们从控制器生成的任何动态内容”,但显然情况并非如此。

它似乎只将页面缓存在内存中,并且磁盘上的文件没有被使用...... 任何人都可以解释这里发生了什么,以及我如何缓存磁盘页面?缓存内存中的所有页面并不实际。谢谢!

+0

Rails是否有可能将文件缓存在内存中的磁盘上(只有当它们不在内存中时才使用它们),然后当我执行Rails.cache.clear时,Rails实际上使内存缓存和磁盘上的文件无效? – Sheldno 2012-03-02 20:55:07

回答

2

有两种形式的缓存的事情:

  • Rack::Cache
  • 页面缓存

页面缓存是caches_page打开什么,以及/公共写入文件。页面缓存是愚蠢的,因为一旦该文件在那里,它将继续得到服务,直到删除它。好处是速度非常快:您通常会配置nginx,apache等来直接处理这些文件,而无需请求任何红宝石。如果你没有运行Nginx的或Apache那么如果导轨被配置为静态资产文件将只获得服务,这是默认关闭的生产(见config.serve_static_assets

Rack::Cache是HTTP识别缓存,因此它可以处理到期时间,告诉你和用户之间可能存在的中间缓存,他们可以缓存什么等。它将缓存的数据存储在你配置的任何存储Rails.cache(文件存储的外观)。任何请求仍然需要通过ruby进行,以便Rack :: Cache可以决定是否返回缓存的数据,还是让请求继续到您的应用程序。

+0

这很有道理,谢谢!回复:原来的问题,为静态页面,然后我本质上必须设置一个Apache的过滤器,检查文​​件的存在,如果它存在服务它?我想这意味着max-age,etags和last_modified在这里不适用(使缓存无效的唯一方法是删除文件)? – Sheldno 2012-03-03 19:25:38

0

这是我尝试安装,我认为会做我想要的一切:

config.cache_store = :dalli_store, '127.0.0.1:11211' 

config.middleware.delete Rack::Cache 
config.middleware.use Rack::Cache, 
    :verbose => true, 
    :metastore => "memcached://127.0.0.1:11211/meta", 
    :entitystore => "file:#{Rails.root}/tmp/cache/rack/body" 

config.action_controller.page_cache_directory = "#{Rails.root}/public/cache" 

这似乎在第一次工作,但我开始收到空白页,当页面陈旧但有效(即返回304) 。我找不到解决这个问题的方法,所以...我不知道如何设置Rack :: Cache来使用文件存储,同时仍然可以使用Rails.cache使用memcached。

我现在使用Rails页面缓存大部分的网站。不幸的是,这有一个缺点,就是维护复杂的清理器,这也意味着需要查询参数的页面必须在expires_in和fresh_when/stale中缓存在内存中。