caching - 过夜预热缓存摘要

标签 caching ruby-on-rails-3.2 cron memcached cache-digests

我们有一个 Rails 3.2 网站,该网站相当大,有数千个 URL。我们为 Russian Doll 缓存实现了 Cache_Digests gem。它运作良好。我们希望通过夜间预热缓存来进一步优化,以便用户在白天获得更好的体验。我看到了这个问题的答案:Rails: Scheduled task to warm up the cache?

是否可以对其进行修改以预热大量 URL?

最佳答案

要以昂贵的加载时间触发许多页面的缓存命中,只需创建一个 rake 任务以迭代地将 Web 请求发送到站点内的所有记录/URL 组合。 (Here is one implementation)

迭代地 Net::HTTP 请求所有站点 URL/记录:

要仅访问每个页面,您可以每晚运行 Rake 任务,以确保清晨用户仍然拥有包含刷新内容的快速页面。

lib/tasks/visit_every_page.rake:

namespace :visit_every_page do
  include Net
  include Rails.application.routes.url_helpers

  task :specializations => :environment do
    puts "Visiting specializations..."
    Specialization.all.sort{ |a,b| a.id <=> b.id }.each do |s|
      begin
        puts "Specialization #{s.id}"
        
        City.all.sort{ |a,b| a.id <=> b.id }.each do |c|
          puts "Specialization City #{c.id}"
          Net::HTTP.get( URI("http://#{APP_CONFIG[:domain]}/specialties/#{s.id}/#{s.token}/refresh_city_cache/#{c.id}.js") )
        end
      
        Division.all.sort{ |a,b| a.id <=> b.id }.each do |d|
          puts "Specialization Division #{d.id}"
          Net::HTTP.get( URI("http://#{APP_CONFIG[:domain]}/specialties/#{s.id}/#{s.token}/refresh_division_cache/#{d.id}.js") )
        end
      end
    end
  end

  # The following methods are defined to fake out the ActionController
  # requirements of the Rails cache
  
  def cache_store
    ActionController::Base.cache_store
  end

  def self.benchmark( *params )
    yield
  end

  def cache_configured?
    true
  end
end

(If you want to directly include cache expiration/recaching into this task, check out this implementation.)

通过自定义 Controller 操作:

如果您需要绕过用户身份验证限制才能访问您的页面,和/或您不想搞砸(太严重)您网站的跟踪分析,您可以创建 custom controller action用于命中缓存摘要 use tokens to bypass authentication :

app/controllers/specializations.rb:

class SpecializationsController < ApplicationController
...
  before_filter :check_token, :only => [:refresh_cache, :refresh_city_cache, :refresh_division_cache]
  skip_authorization_check :only => [:refresh_cache, :refresh_city_cache, :refresh_division_cache]

...

  def refresh_cache
    @specialization = Specialization.find(params[:id])
    @feedback = FeedbackItem.new
    render :show, :layout => 'ajax'
  end

  def refresh_city_cache
    @specialization = Specialization.find(params[:id])
    @city = City.find(params[:city_id])
    render 'refresh_city.js'
  end

  def refresh_division_cache
    @specialization = Specialization.find(params[:id])
    @division = Division.find(params[:division_id])
    render 'refresh_division.js'
  end

end

我们的自定义 Controller 操作会呈现其他加载成本高昂的页面的 View ,从而导致这些页面的缓存命中。例如。 refresh_cache 呈现与 controller#show 相同的 View 页面和数据,因此请求 refresh_cache 将为这些记录预热与 controller#show 相同的缓存摘要。

安全说明:

出于安全原因,我建议在提供对您传入 token and check it 的任何自定义 refresh_cache Controller 请求的访问权限之前确保it corresponds with a unique token for that record.在提供访问权限之前将 URL token 与数据库记录进行匹配(如上所示)非常简单,因为您的 Rake 任务可以访问每条记录的唯一 token - 只需在每个请求中传递记录的 token 即可。

tl;博士:

要触发数千个站点 URL/缓存摘要,请创建一个 rake 任务来迭代请求站点中的每个记录/URL 组合。您可以通过创建一个自定义 Controller 操作(通过 token 对访问进行身份验证)来绕过应用对此任务的用户身份验证限制。

关于caching - 过夜预热缓存摘要,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29301780/

相关文章:

java - Spring 可缓存除非条件不起作用

ruby-on-rails-3.2 - yml文件中的devise.registrations.reasons已弃用?

asset-pipeline - 仅使用 Rails 3.2 + Sprockets + LESS 的相关资源

go - 我如何将脚本部署到仅在预定时间运行的 heroku

python - Crontab 使用错误版本的 Python 运行脚本

java - 关于提高高速缓存密集型系统的效率

Asp.net 全局输出缓存

cron - 如何让 crontab 在上午 10 点到晚上 10 点之间每 2 小时执行一次?

windows - Windows NT 是否缓存或刷新 INI 文件写入内容?

ruby-on-rails - Rails 应用程序中包含 Javascript 的问题