Rails3.2什么时候使用缓存到磁盘的页面



在旧的Rails项目中,页面缓存的工作方式正如我从在线阅读文档中所期望的那样,而在Rails 3.1/3.2中,它的工作方式不同。看起来Rails将页面写入磁盘,但从不使用它们(所以我认为它是在内存中缓存页面)。

(请耐心听我的长篇大论,它并不复杂,只是彻底…)

在一个新的Rails 3.2.2应用程序中,我有以下内容:

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

当我在生产中启动服务器并访问localhost时,我看到:

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

如果我直接编辑public/index.html文件并点击ctrl+r或ctrl+shift+r,我看不到我对该文件所做的更改。

如果我打开一个rails控制台并键入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)

我对public/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将在公共目录中提供任何静态文件,而不是我们从控制器生成的任何动态内容",但显然不是这样。

页面似乎只缓存在内存中,磁盘上的文件没有被使用有人能解释一下这里发生了什么,以及我如何在磁盘上缓存页面吗将所有页面都缓存在内存中是不现实的。谢谢

有两种形式的缓存:

  • Rack::Cache
  • 页面缓存

页面缓存是caches_page打开的功能,并在/public中写入文件。页面缓存是愚蠢的,因为一旦文件在那里,它就会一直得到服务,直到有东西删除它。好处是它非常快:你通常会配置nginx、apache等直接为这些文件提供服务,而请求永远不会碰到ruby。如果你没有运行nginx或apache,那么只有当rails被配置为服务静态资产时,该文件才会得到服务,而在生产中默认情况下是关闭的(请参阅config.serve_static_assets

Rack::Cache是一个支持http的缓存,因此它可以处理到期时间,告诉您和用户之间可能存在的中间缓存,它们可以缓存什么等等。它将缓存的数据存储在您将Rails.cache配置为的任何存储中(根据其外观进行文件存储)。任何请求仍然必须通过ruby,因此Rack::Cache可以决定是否返回缓存的数据,或者是否让请求继续到您的应用程序。

这是我尝试的设置,我认为它可以做我想做的一切:

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_whin/state缓存在内存中。

最新更新