我正在这里构建一个类似IFTTT的平台。
简而言之,rufus调度器非常棒。我知道它使用线程池(默认为28个线程?=>3.x.x)
我的平台预计将处理1000多个时间表,可能不止这些。
Jruby上的Singleton。这种期望是否存在性能问题?我应该增加线程池的最大大小吗?那么我应该增加多少线程?这个问题有指南吗?
我完成了基准测试,代码如下。。我的系统中有一个作业队列,所以rufus调度器的处理程序将只执行非常短和轻的任务。例如排队作业。在代码中,只记录job.last_time和time之间的间隔。我认为间隔越大,性能就越低。类似"延迟"
require 'rufus-scheduler'
require 'awesome_print'
require 'logger'
SCHEDULE_COUNT = 1000
MAX_THREAD = 224
schedule_samples = { type: "cron", schedule: "* * * * *"}
$logger = Logger.new("benchmark.log")
scheduler = Rufus::Scheduler.singleton(:max_work_threads => MAX_THREAD)
class Handler
def self.call(job, time)
$logger.info job.last_time - time
end
end
SCHEDULE_COUNT.times do
scheduler.send( schedule_samples[:type].to_sym, schedule_samples[:schedule], Handler)
end
sleep 600
结果有点失望。。线程越多越好。但我得到了我未来系统的大致延迟,这是可以接受的。
我在我的笔记本电脑上运行了这段代码,1核1GB RHEL 64位Vmware和4核4GB RHEL 64bit Vmware。
Jruby版本
- labtop jruby 1.7.16.1(1.9.3p92)
- Linux jruby 1.7.19(1.9.3p551)
这些不完全一样,但应该没问题。。?链接图是所有间隔的平均值。基准结果
我可以不断增加最大线程数来找出性能峰值。但我决定不这么做。为了生产环境,我会用更好的机器。1000到2000毫秒的延迟应该不是问题。(在基准中,1核心的最大延迟为700ms)
再次,Rufus Scheduler很棒
Rufus调度器按照"先触发后"的顺序对其调度进行排队。因此,你的列表可能会变长,但rufus并不是每次都在整个列表中循环(每次意味着大约每0.3秒(默认频率)),只要下一个元素是"在未来",它就会停止迭代。所以一长串应该没问题。
读到这个问题,我觉得你更关心的是很多时间表同时触发和/或重叠。IIRC,JRuby使用Java线程,据说这些线程对多核友好,所以好的硬件可能会有所帮助。
你为什么不造一个原型呢?你用时间表轰炸它,观察、学习、调整(如果不够好,可能会放弃rufus时间表)。建立你的基准,然后你的问题就会得到答案。