使用延迟作业进行页面缓存

set*_*rgo 4 optimization caching ruby-on-rails ruby-on-rails-3

嘿所有,如果你曾经发表过[craigslist],这个问题应该对你有意义.每当您发布商品(例如,出售家具或公寓)时,您的商家信息不会立即被列入网站.相反,列表将每10-15分钟分批出现(数量不同).起初我真的过度思考这种行为,试图保存记录然后进行批量插入,但我意识到它更简单.在与一些同事交谈之后,Craigslist正在缓存他们的页面然后每10-15分钟清空一次缓存就有意义了.这严重降低了数据库的负载.

现在,我的问题.我如何在Rails中完成同样的事情?我知道如何实现缓存 - 我已经阅读了[使用Rails指南进行缓存].我将使用动作缓存和片段缓存(因为我无法缓存整个页面).我仍然需要进行验证和访问控制,所以我无法完全缓存页面...

vri*_*h88 5

要实现定时页面缓存,您可以使用标准的Rails缓存加上一点时间的聪明.

首先,您要确定缓存级别.你有三个选择:

  1. 页面缓存 - 缓存整个页面,但后续请求不会通过Rails堆栈.因此,如果这是一个Craiglist-esque页面,每秒会被命中几千次,那么这个请求只会转到你的网络服务器(例如apache)而不是Rails,或者你的数据库会让它更快.权衡是您丢失了Rails提供的身份验证,会话变量等.
  2. 操作缓存 - 缓存整个页面,但将请求带入Rails,以便它可以执行与该操作关联的任何过滤器.
  3. 片段缓存 - 缓存页面的一部分,基本上绕过了在块中执行代码的需要(以及对数据库的任何后续调用).

然后,您需要选择适当级别的缓存并在您的应用程序中实现它(请查看上面的链接以获取实现示例).

一旦实现了缓存,您现在必须找到一种使缓存过期的方法.我可以想到两种方法来做到这一点,都有好处和缺点.现在让我们假设你选择使用动作缓存.

  1. 可靠但更复杂 - 在控制器中创建一个到期缓存的操作和一个对该操作发出请求的cron作业任务.我问了一个类似的问题来解决这个"内置"计划任务.对于安全预防措施,您可能希望包含生成的哈希或类似内容,以便有人无法通过转到'/ products/expire_cache'手动使缓存过期.

    class ProductsController < ApplicationController
      caches_action :index
    
      def index
        # implementation
      end
    
      def expire_cache
        if params[:verification_hash] == 'sa89sf8sfsfehiwaf89yfea98fh'
          expire_action :action => :index
        end
      end
    end
    
    Run Code Online (Sandbox Code Playgroud)
  2. 不可靠但更简单 - 只需使用任意条件使操作中的缓存失效.此实现假设将有足够的流量来定期确保有人将在0,15,30和45分钟内访问您的站点.您可以减少此间隔,以确保以更可能的间隔重置缓存.

    class ProductsController < ApplicationController
      caches_action :index
    
      def index
        # implementation
        expire_action :action => :index if Time.now.min % 15 == 0
      end
    end
    
    Run Code Online (Sandbox Code Playgroud)