【问题标题】:Removing Cache Busting in Rails Production在 Rails 生产环境中移除缓存破坏
【发布时间】:2010-09-16 00:43:15
【问题描述】:

当我在生产模式下部署 Rails 应用程序时,它会将日期时间字符串作为查询参数附加到所有静态资产 URL 的末尾。这是为了防止浏览器在我重新部署应用程序后使用过时的资产缓存副本。

有没有办法让 Rails 使用自上次部署以来未更改的资产(以及未更改的资产)的旧时间戳。我想这样做是为了防止用户不得不重新下载那些未更改的资产。

【问题讨论】:

  • 请注意,从 rails 3.1 Rails 开始使用 MD5 而不是 Timestamps,这意味着这个问题不再相关。

标签: ruby-on-rails deployment caching


【解决方案1】:

默认情况下,Capistrano 会触及它认为是“资产”的每个文件。正如你所说,这意味着在每次部署之后,rails 都认为每个资产都发生了变化,并且浏览器每次都会下载更新的版本。

您可以在 Capistrano 中使用以下设置禁用此功能

set :normalize_asset_timestamps, false

如果您使用的是 SVN,那么文件的修改日期应该反映它们在您的存储库中的最后修改日期,所以这应该是完美的。

如果您使用的是 Apache,您可以添加类似的内容来真正让缓存为您工作。这有助于告诉浏览器依赖“缓存控制”指令,这意味着如果它知道资产被缓存,它甚至不会费心去请求它。

#Etags should be based on the file parameters only (default includes INode)
FileETag MTime Size  

#Rewrite stuff
RewriteEngine On  

#This sets the environment variable (is_versioned) when the URL query string
#looks like ?874353948543  or any string of digits
RewriteCond %{QUERY_STRING} ^[0-9]+$
RewriteRule ^(.*)$ $1 [env=is_versioned:true]  

<Directory /deployed-rails-app/public/ >
    Options -Indexes FollowSymLinks -MultiViews
    AllowOverride None
    Order allow,deny
    allow from all  

    #For files, force the browser to rely on cache-control directives and 
    #Rails asset timestamps by removing Etags and Last-Modified dates  

    #For all assets that aren't stamped by rails, cache them for ~ 3 hours
    Header set "Cache-Control" "max-age=10000"
    Header unset Etag
    Header unset "Last-Modified"  

    #For all assets that ARE stamped by rails, cache them for 30 days
    Header set "Cache-Control" "max-age=2592000" env=is_versioned

</Directory>

我已经以这种方式设置了我的生产服务器,现在返回访问者只执行一个请求 (Get /),该请求返回动态内容并且所有资产 (~ 40 - 50) 都被缓存。

【讨论】:

  • 神圣的鳄梨酱,两年前?为什么没有人拉皮条这个解决方案。除了在每个请求的 URL 上运行(简单)正则表达式的开销之外,我喜欢它。
【解决方案2】:

我认为您可以使用 ENV['RAILS_ASSET_ID'] 来更改缓存清除资产 ID。不幸的是,这适用于所有资产。

但如果未设置,则使用资源的源修改时间。如果该文件自您上次使用以来没有被修改过,那应该不是问题。

如果资产 ID 在未更改的情况下发生更改,则可能是因为您的部署过程改变了修改时间,也许您可​​以考虑对其进行调整。

最后,您可以随时override rails_asset_id with your own custom method

希望这会有所帮助。

【讨论】:

    【解决方案3】:

    @Aupajo 我喜欢这个,但我想我可以更进一步。这里的问题是 capistrano 确实会在每次部署时创建所有文件的新副本,因此所有缓存清除字符串都会更改。但是,文件的 MD5 只会在文件内容更改时更改。

    当然,生成一个MD5既昂贵又慢,但是你可以把一个文件的MD5缓存在memcache中,(关键是改变时间,好像时间改变了MD5可能有已更改,但如果时间戳未更改,则 MD5 不会已更改

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-11
      • 1970-01-01
      • 2021-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-26
      相关资源
      最近更新 更多