石英性能

vik*_*kas 18 java quartz-scheduler

似乎Quartz调度程序每秒可以运行的作业数量有限制.在我们的场景中,我们每秒大约有20个作业以24x7的速度启动,而石英每秒可以运行多达10个作业(有100个石英线程和100个数据库连接池大小用于JDBC支持的JobStore),但是,当我们将它增加到20个时每秒工作,石英变得非常慢,其触发的工作与他们的实际预定时间相比非常晚,造成许多失火并最终显着降低系统的整体性能.一个有趣的事实是,JobExecutionContext.getScheduledFireTime().getTime()对于这样的延迟触发,在他们的安排时间之后变为10-20甚至更多分钟.

石英调度程序每秒可运行多少个作业而不影响作业的预定时间,这些负载的最佳石英线数应该是多少?

或者我在这里遗漏了什么?

关于我们想要实现的目标的细节:

我们有近10k项目(分为2个或更多类别,在目前情况下我们有2个类别),我们需要在给定频率下进行一些处理,例如15,30,60 ...分钟,这些项目应在该频率内处理每分钟给定油门.例如,假设60分钟频率,每个类别的5k项目应该以每分钟500项的节流进行处理.因此,理想情况下,这些物品应在一天中每小时的前10(5000/500)分钟内处理,每分钟有500件待处理的物品,这些物品在每分钟的每一秒均匀分布,因此我们将大约8-一个类别每秒9项.

现在为了实现这一目标,我们使用Quartz作为调度程序来触发处理这些项目的作业.但是,我们不会在Job.execute方法中处理每个项目,因为每个项目处理需要5-50秒(平均到30秒),这涉及webservice调用.我们宁愿为JMS队列上的每个项目处理推送消息,而单独的服务器机器处理这些作业.我注意到Job.execute方法花费的时间不超过30毫秒.

服务器细节:

Solaris Sparc 64位服务器,带有8/16内核/线程cpu,用于具有16GB RAM的调度程序,我们在调度程序集群中有两台这样的机器.

maa*_*asg 11

在之前的项目中,我遇到了同样的问题.在我们的例子中,Quartz表现出了一秒钟的粒度.亚秒级调度是一个延伸,正如您所观察到的那样,经常发生失火并且系统变得不可靠.

通过创建两个级别的调度解决了这个问题:Quartz将安排n个连续作业的作业"设置".使用集群Quartz,这意味着系统中的给定服务器将使该作业"设置"以执行.然后,集合中的n个任务由"微调度器"接收:基本上是一个使用本机JDK API进一步将作业计时到10ms粒度的定时工具.

为了处理单个作业,我们使用了一个主工作者设计,其中主人负责将作业的预定交付(限制)处理到多线程工作者池.

如果我今天必须再次这样做,我依靠ScheduledThreadPoolExecutor来管理'微调度'.对于您的情况,它看起来像这样:

ScheduledThreadPoolExecutor scheduledExecutor;
...
    scheduledExecutor = new ScheduledThreadPoolExecutor(THREAD_POOL_SIZE);
...

// Evenly spread the execution of a set of tasks over a period of time
public void schedule(Set<Task> taskSet, long timePeriod, TimeUnit timeUnit) {
    if (taskSet.isEmpty()) return; // or indicate some failure ...
    long period = TimeUnit.MILLISECOND.convert(timePeriod, timeUnit);
    long delay = period/taskSet.size();
    long accumulativeDelay = 0;
    for (Task task:taskSet) {
        scheduledExecutor.schedule(task, accumulativeDelay, TimeUnit.MILLISECOND);
        accumulativeDelay += delay;
    }
}
Run Code Online (Sandbox Code Playgroud)

这使您可以大致了解如何使用JDK工具来微调任务.(免责声明:您需要为prod环境提供强大功能,例如检查失败的任务,管理重试(如果支持)等等).

通过一些测试+调优,我们发现了Quartz作业与一个预定集中的作业数量之间的最佳平衡.

我们以这种方式经历了100倍的吞吐量改进.网络带宽是我们的实际限制.


Tom*_*icz 6

首先检查如何提高JDBC-JobStore的性能?在Quartz文档中.

正如你可能猜到的那样,存在绝对值和明确的指标.这一切都取决于您的设置.但是这里有一些提示:

  • 每秒20个作业意味着每秒大约100个数据库查询,包括更新和锁定.那是非常多的!

  • 考虑将Quartz设置分发到群集.但是,如果数据库是一个瓶颈,它将无济于事.也许TerracottaJobStore会来救援?

  • K系统中拥有核心,所有内容都K将少于您的系统未充分利用.如果你的工作是CPU密集型的,那K很好.如果他们呼叫外部Web服务,阻止或睡眠,请考虑更大的值.但是,由于上下文切换,超过100-200个线程会显着降低系统速度.

  • 你尝试过分析吗?你的机器大部分时间都在做什么?你可以发布线程转储吗?我怀疑数据库性能不佳而不是CPU,但这取决于你的用例.