4

使用 Rails 3.1.1 和 Herkou

我的应用中有 1.000 种产品。它们都有一个非常慢的控制器,可以通过片段缓存有效地解决。尽管数据不会经常更改,但它仍然需要定期过期(我通过扫描来完成),在我的情况下是每周一次。

现在,在扫描缓存视图之后,我不希望我的用户通过尝试一个接一个地访问产品来创建新片段(第一次加载大约需要 6-8 秒,缓存加载需要 2-3 秒)。我假设我可以使用某种脚本来执行此操作,该脚本将一个一个地加载每个产品页面,从而使服务器创建这些片段。

我可以想象这可以通过三种方式处理:

  1. 在我的本地机器上运行一个脚本,该脚本将尝试使用某种 get 命令访问每个 url - 缺点:不是很漂亮,并且会以我不喜欢的方式影响访问者统计信息。

  2. 在清扫器之后在服务器上运行相同类型的脚本,这将加载每个产品。在这种情况下,我该怎么做?

  3. 使用智能 Rails 命令自动执行此操作。有这么优雅的命令吗?

4

2 回答 2

0

创建一个作为 rake 任务运行的脚本,或者更好的是一个 worker,它运行并卷曲页面。当您可以调用 curl 时,无需包含 gem

`curl -A "CacheRefresher" #{ENV['HOSTNAME']}/api/v1/#{klass.name.underscore.pluralize}/#{id} >/dev/null 2>&1` 
于 2015-04-10T19:28:26.623 回答
0

我制作了这个脚本,它可以工作。“product.slug”是因为我安装了friendly_id。它将生成名称为 www.mydomain.com/productabc-123/ 的 url 变量,Nokogiri 将读取这些变量(此解决方案需要 Nokogiri gem)。

请注意,我在此解决方案中从片段缓存切换到动作缓存(与我使用片段缓存的问题相反)。重要的区别是当我检查缓存时if Rails.cache.exist?('views/www.mydomain.com/' + product.slug)。对于 fragment_caching,它应该是那里的片段名称。

require 'nokogiri'
require 'open-uri'

Product.all.each do |product|
  url = 'http://www.mydomain.com/' + product.slug  
  begin      
    if Rails.cache.exist?('views/www.mydomain.com/' + product.slug)     
      puts url + " is already in cache"
    else
      doc = Nokogiri::HTML(open(url))
      puts "Reads " + url
# Verifies if the caching worked. Only for trouble shooting
      if Rails.cache.exist?('views/www.mydomain.com/' + product.slug)     
        puts "--->" + url + " is NOW in the cache"
      else
        puts "--->" + url + " is still not in the cache!"
      end
      sleep 1
    end
  rescue
    puts 'Normal rescue of ' + url
  rescue Timeout::Error
    puts 'Timeout rescue of ' + url
    puts 'Sleep for 5 sec'
    sleep 5
    retry
  end
end
于 2012-10-30T05:52:32.303 回答