【问题标题】:Rails 3.2 Rack::Cache HTTP Headers and Action CachingRails 3.2 Rack::Cache HTTP 标头和动作缓存
【发布时间】:2012-06-05 06:27:30
【问题描述】:

下午好,

我在尝试将 HTTP 缓存与 Rack::Cache 和动作缓存结合起来时遇到了一些问题(在我的 Heroku 托管应用程序上)。

单独使用它们,它似乎工作。启用动作缓存后,页面加载速度很快,日志会提示它正在缓存。通过控制器(eTag、last_modified 和 fresh_when)中的 HTTP 缓存,似乎设置了正确的标头。

但是,当我尝试将两者结合起来时,它似乎是动作缓存,但 HTTP 标头始终是 max_age: 0, must_revalidate。为什么是这样?我做错了吗?

例如,这是我的“home”操作中的代码:

class StaticPagesController < ApplicationController
  layout 'public'

  caches_action :about, :contact, ......, :home, .....

  ......

  def home
    last_modified = File.mtime("#{Rails.root}/app/views/static_pages/home.html.haml")
    fresh_when last_modified: last_modified , public: true, etag: last_modified
    expires_in 10.seconds, :public => true       
  end

出于所有意图和目的,这应该有一个 max-age 10 no 的公共缓存控制标签?

$ curl -I http://myapp-staging.herokuapp.com/

HTTP/1.1 200 OK
Cache-Control: max-age=0, private, must-revalidate
Content-Type: text/html; charset=utf-8
Date: Thu, 24 May 2012 06:50:45 GMT
Etag: "997dacac05aa4c73f5a6861c9f5a9db0"
Status: 200 OK
Vary: Accept-Encoding
X-Rack-Cache: stale, invalid
X-Request-Id: 078d86423f234da1ac41b418825618c2
X-Runtime: 0.005902
X-Ua-Compatible: IE=Edge,chrome=1
Connection: keep-alive

配置信息:

# Use a different cache store in production
config.cache_store = :dalli_store

config.action_dispatch.rack_cache = {
  :verbose      => true,
  :metastore => "memcached://#{ENV['MEMCACHE_SERVERS']}",
  :entitystore => "memcached://#{ENV['MEMCACHE_SERVERS']}"#,
}

在我看来,您应该能够使用动作缓存以及反向代理,对吗?我知道他们做的事情非常相似(如果页面发生变化,代理和动作缓存都将无效并需要重新生成),但我觉得我应该能够同时拥有两者。还是我应该摆脱一个?

更新

感谢下面的回答!它似乎工作。但是为了避免必须为每个控制器操作编写 set_XXX_cache_header 方法,您是否发现这不起作用的任何原因?

before_filter :set_http_cache_headers

.....

def set_http_cache_headers
  expires_in 10.seconds, :public => true
  last_modified = File.mtime("#{Rails.root}/app/views/static_pages/#{params[:action]}.html.haml")
  fresh_when last_modified: last_modified , public: true, etag: last_modified
end

【问题讨论】:

    标签: ruby-on-rails caching reverse-proxy rack-cache


    【解决方案1】:

    当您使用动作缓存时,只会缓存响应正文和内容类型。后续请求不会对响应进行任何其他更改。

    但是,即使动作本身被缓存,动作缓存也会运行任何之前的过滤器。

    所以,你可以这样做:

    class StaticPagesController < ApplicationController
      layout 'public'
    
      before_filter :set_home_cache_headers, :only => [:home]
    
      caches_action :about, :contact, ......, :home, .....
    
      ......
    
      def set_home_cache_headers
        last_modified = File.mtime("#{Rails.root}/app/views/static_pages/home.html.haml")
        fresh_when last_modified: last_modified , public: true, etag: last_modified
        expires_in 10.seconds, public: true       
      end
    

    【讨论】:

    • 感谢您的意见!我会试一试,看看它对我有什么作用。
    • 这似乎有效!但是,如果您不介意检查一下,我确实在更新中有一个简短的问题(一种避免编写 18 个单独方法的潜在方法)。
    • 请注意,before_filter 确实需要在调用 caches_action 之前列出(如上所示),以确保过滤器以正确的顺序运行,因为这让我感到困惑首先。
    猜你喜欢
    • 2012-01-17
    • 1970-01-01
    • 2012-04-27
    • 2012-08-28
    • 2012-04-13
    • 2016-06-29
    • 2011-07-20
    • 2017-11-17
    • 2011-09-01
    相关资源
    最近更新 更多