什么会导致Rails页面缓存停止工作?

时间:2009-06-02 19:01:31

标签: ruby-on-rails ruby .htaccess caching

我有一个Rails应用程序已经停止了某个地方的缓存,而且我不确定一路上哪个版本可能会阻止它工作。

我的印象是页面缓存在正常工作时,如果找到缓存文件,就不应该点击Rails。但是,当加载我的页面并监视production.log时,它会同时命中Rails和DB。

我有一个清除器设置清除缓存:create,:update和:destroy。它工作正常,因为只要其中一个事件发生,就会更新/public/cache/index.html文件。我一开始认为可能是因为我正在使用OutputCompression插件,但删除它有相同的结果,所以我把它放回去.index.html就在那里,但.htaccess和Rails忽略它并重建整个页面,包括重写缓存的index.html。

以下是代码的相关部分(除非我遗漏了一些内容):

控制器:

class SecretsController < ApplicationController
  caches_page :index
  cache_sweeper :secret_sweeper, :only => [:create, :update, :destroy]

  # snipped
end

htaccess的:

RewriteEngine On

# Rewrite index to check for cached
RewriteRule ^/$ /cache/index.html [QSA]
RewriteRule ^$ /cache/index.html [QSA]
RewriteRule ^([^.]+)$ $1.html [QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]

Firebug响应标题

Date: Tue, 02 Jun 2009 18:50:36 GMT
Server: Apache/1.3.41 (Unix) mod_fastcgi/2.4.2 PHP/5.2.9 mod_log_bytes/1.2 mod_bwlimited/1.4 mod_auth_passthrough/1.8 FrontPage/5.0.2.2635 mod_ssl/2.8.31 OpenSSL/0.9.8b
Vary: Accept-Encoding
X-Runtime: 0.05637
Etag: "4f3497a74141d1e92ae7a1fe4d5dc1d2"
Cache-Control: private, max-age=0, must-revalidate
Content-Encoding: gzip
Content-Length: 22356
Connection: close
Content-Type: text/html; charset=utf-8
default-style: tms

我希望能够使用mod_gzip,但是ASmallOrange不支持它,而DreamHost则支持它(在我们的价格增加三倍之前)。

无论如何,任何人都可以解释为什么Rails忽略了缓存的index.html?我假设它是.htaccess中的东西,因为如果它正常工作它永远不会触及Rails。

编辑:缓存问题是RewriteRules上的第一个斜杠。在我将它们都更改为“cache / index.html”之前,它没有找到缓存的文件,现在缓存工作正常。

但是,现在我必须删除OutputCompression调用,因为它返回文件的gzip压缩版本,Content-Type设置为“text / html”。知道如何让它为该文件发送正确的内容类型吗?这是整个应用程序中唯一缓存的内容。

再次编辑:将.htaccess更改为此对gzip问题没有帮助:

RewriteRule ^/$ cache/index.html [QSA,T=application/x-gzip]
RewriteRule ^$ cache/index.html [QSA,T=application/x-gzip]

除非禁用压缩,否则它仍会显示为zip文件(即乱码)的文本表示形式。但缓存工作非常完美。

3 个答案:

答案 0 :(得分:1)

为什么要使用OutputCompression插件? Apache可以为您做到这一点。查看mod_deflate

以下是我使用的规则:

# Deflate
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css application/javascript application/x-java
script
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

这将压缩应用程序的所有文本输出,静态和动态。

只是一个猜测,但我想这也更快,因为它是用C语言编写的Apache模块。

答案 1 :(得分:0)

我会检查你的ETag配置。如果您使用多个Web服务器并且未将其配置为独立于为该文件提供服务的计算机,则可能经常阻止正确缓存文件。

答案 2 :(得分:0)

最后找出了问题,经过10周的停机后我的网站再次上线了。一旦我得到它来加载缓存文件,我发现另一个问题是OutputCompression插件将文件压缩为.gz文件,但Rails将其保存为.html,并且Apache将其作为text / html服务,结果在胡言乱语。

解决了我的问题的修复:

在.htaccess中:

AddEncoding x-gzip .gz
AddType text/html .gz

RewriteRule ^/$ cache/index.gz [QSA]
RewriteRule ^$ cache/index.gz [QSA]

在config / environments.rb中:

ActionController::Base.page_cache_extension = ".gz"

Ruby代码使“caches”指令保存为“cache / index.gz”而不是“cache / index.html”。 AddEncoding告诉它不要将它作为html提供,但它本身只会显示页面源,因为它默认为Content-Type为“text / plain”。 将AddType更改,以便.gz文件作为“text / html”提供,从而导致正确显示。

这可能对每个人都不起作用,但由于我不在网站的任何地方提供.gz文件,而且首页是唯一一个缓存的页面,这对我来说非常适合。

感谢大家的帮助。