0

Rails 有一组很好的过滤器(before_validation、before_create、after_save 等)以及对观察者的支持,但我面临的情况是,依赖过滤器或观察者在计算上过于昂贵。我需要一个替代方案。

问题:我正在记录对大量页面的 Web 服务器点击。我需要的是一个触发器,它会在给定页面的浏览次数超过 X 次时执行操作(例如,发送电子邮件)。由于页面和点击量巨大,使用过滤器或观察器会浪费大量时间,因为 99% 的时间,它测试的条件都是错误的。电子邮件不必立即发送(即可以接受 5-10 分钟的延迟)。

相反,我考虑的是实现某种流程,每 5 分钟左右扫描一次数据库,并检查哪些页面被点击超过 X 次,在新的数据库表中记录该状态,然后发送相应的电子邮件。它并不完全优雅,但它会起作用。

还有其他人有更好的主意吗?

4

4 回答 4

1

耙任务很好!但是您最终将为您添加的每个后台作业编写更多自定义代码。查看延迟作业插件http://blog.leetsoft.com/2008/2/17/delayed-job-dj

DJ 是一个异步优先级队列,它依赖于一个简单的数据库表。根据 DJ 网站,您可以使用如下所示的Delayed::Job.enqueue()方法创建作业。

class NewsletterJob < Struct.new(:text, :emails)
  def perform
    emails.each { |e| NewsletterMailer.deliver_text_to_email(text, e) }
  end    
end  

Delayed::Job.enqueue( NewsletterJob.new("blah blah", Customers.find(:all).collect(&:email)) )
于 2009-05-22T22:52:09.260 回答
1

我曾经是编写自定义广告服务器的团队的一员,该服务器具有相同的要求:监控每个文档的点击次数,并在达到特定阈值时执行某些操作。该服务器将为现有的非常大的站点提供大量流量,并且可扩展性是一个真正的问题。我的公司聘请了两名 Doubleclick 顾问来挑选他们的大脑。

他们的意见是:保存任何信息的最快方法是将其写入自定义 Apache 日志指令。所以我们建立了一个网站,每次有人点击一个文档(广告、页面,都一样),处理请求的服务器会在日志中写入一条 SQL 语句:“INSERT INTO Impressions (timestamp, page, ip, etc) ) VALUES (x, 'path/to/doc', y, etc);" -- 所有动态输出都来自网络服务器的数据。每 5 分钟,我们会从 Web 服务器收集这些文件,然后一次将它们全部转储到主数据库中。然后,在闲暇时,我们可以解析这些数据以做任何我们满意的事情。

根据您的确切要求和部署设置,您可以执行类似的操作。检查您是否超过某个阈值的计算要求可能仍然比执行 SQL 以增加值或插入行更小(在这里猜测)。您可以通过记录命中(特殊格式或非特殊格式)来消除这两种开销,然后定期收集它们,解析它们,将它们输入数据库,然后对它们做任何你想做的事情。

于 2009-05-23T15:53:14.530 回答
0

保存 Hit 模型时,更新 Page 模型中的一个冗余列,该列存储运行中的命中总数,这会花费您 2 个额外的查询,因此每个命中可能需要两倍的时间来处理,但您可以决定是否需要发送带有简单 if 的电子邮件。

您的原始解决方案也不错。

于 2009-05-22T22:07:05.730 回答
0

我必须在这里写一些东西,以便 stackoverflow 代码突出显示第一行。

class ApplicationController < ActionController::Base
  before_filter :increment_fancy_counter

  private

  def increment_fancy_counter
    # somehow increment the counter here
  end
end

# lib/tasks/fancy_counter.rake
namespace :fancy_counter do
  task :process do
    # somehow process the counter here
  end
end

让一个 cron 作业运行,rake fancy_counter:process但你希望它经常运行。

于 2009-05-22T22:09:07.317 回答