代码之家  ›  专栏  ›  技术社区  ›  Chris Doggett

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

  •  2
  • Chris Doggett  · 技术社区  · 17 年前

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

    我的印象是,页面缓存在正常工作的情况下,如果Rails找到了缓存的文件,它甚至永远不会命中Rails。然而,在加载我的页面并监控product.log时,它同时影响了Rails和数据库。

    我设置了一个清理程序,用于清除: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
    

    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。

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

    :将.htaccess更改为this无助于解决gzip问题:

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

    除非禁用压缩,否则它仍然显示为zip文件的文本表示形式(即乱码)。不过,缓存工作得很好。

    3 回复  |  直到 17 年前
        1
  •  1
  •   Luke Francl    17 年前

    为什么要使用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
    

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

        2
  •  0
  •   Kevin    17 年前

    我会检查你的ETag配置。如果您使用多个web服务器,并且未将其配置为独立于提供文件的机器,则这通常会妨碍文件的正确缓存。

        3
  •  0
  •   Chris Doggett    16 年前

    解决我问题的修复程序:

    在.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,但它本身只显示页面源,因为它默认为“text/plain”的Content-Type。AddType会更改内容,使.gz文件作为“text/html”提供,从而实现正确的显示。

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

    感谢大家的帮助。