Java 石英建筑Q-或多或少的工作
我正在将我的Tomcat应用程序转换为使用Quartz调度程序。我使用它主要是在后台触发电子邮件进程,我担心并发作业会使处理器无法承受。所以这是一个最佳实践问题 Q) 生成一个quartz作业(例如每小时一次)并让它连续调用多个例程是否更好?这样,在例行程序1完成之前,例行程序2不会启动 还是将每个例程安排为单独的Quartz作业并限制线程数更好 如果调度了更多线程可用的作业,会发生什么情况。他们只是排队吗?i、 这能成为我的控制机制吗。我已经使用指令来防止并发的相同作业 我不想同时运行三个类似的作业。它不依赖于时间,因此串行处理在处理器上更容易实现 最直接的架构是什么Java 石英建筑Q-或多或少的工作,java,multithreading,quartz-scheduler,Java,Multithreading,Quartz Scheduler,我正在将我的Tomcat应用程序转换为使用Quartz调度程序。我使用它主要是在后台触发电子邮件进程,我担心并发作业会使处理器无法承受。所以这是一个最佳实践问题 Q) 生成一个quartz作业(例如每小时一次)并让它连续调用多个例程是否更好?这样,在例行程序1完成之前,例行程序2不会启动 还是将每个例程安排为单独的Quartz作业并限制线程数更好 如果调度了更多线程可用的作业,会发生什么情况。他们只是排队吗?i、 这能成为我的控制机制吗。我已经使用指令来防止并发的相同作业 我不想同时运行三个类似
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
public class HourJob implements Job, InterruptableJob {
boolean interrupted = false;
String cls = this.getClass().getName();
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println(cls+"-Start");
for(int i=1; i<15; i++){
try { //do work
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(interrupted){
System.out.println(cls+"-Interrupted");
return;
}
}//for
System.out.println(cls+"-Exit");
}
@Override
public void interrupt() throws UnableToInterruptJobException {
interrupted = true;
}
}
及
这是一个间接的回答,但我们就是这么做的:
由于我们使用Quartz来安排许多类型的任务,我们不希望某个作业占用太多资源,从而影响其他作业 因此,我们最终拆分了流程:
*Quartz作业只是将数据推送到作业队列中(每种作业类型不同)
*我们配置了执行服务(很容易扩展)从队列中读取数据并执行实际的作业(无论是发送电子邮件还是其他批处理操作) 我们现在有数千个作业在运行时没有并发问题,并且能够轻松地按作业类型进行扩展
- 从设计的角度来看,如果每个例程在概念上是独立的,我建议将它们作为一个单独的石英作业。这样,如果其中一个在运行过程中出错,其他执行和完成状态将不会受到影响,您将能够在需要时单独应用事件侦听器等。此外,您还将能够独立控制每个侦听器的计划
- 根据quartz文件:
- 但是,如果同时有多个作业尝试运行,并且您配置的线程数小于这些作业的数量,则找不到线程的线程将被视为未启动:
每种触发器的默认策略都不同,但它通常会在线程可用时立即运行丢失的触发器。在任何情况下,您都需要查看所使用的触发器的策略,并将其更改为所需的策略我实际上已经在这样做了。我实际上要控制的是处理队列的作业。今天我要用线程运行它,它变得有点复杂。我不确定我是否完全理解:如果它(过载)在石英中,那么你可以通过设置它的缺火策略(忽略错过的运行、立即运行等)来配置触发器的行为。如果它(过载)在从队列中读取的作业中,这实际上取决于您的应用程序业务逻辑,不是关于Quartz的问题,而是您的队列和应用程序逻辑。太好了!正是我想要的信息。谢谢
public void contextInitialized(ServletContextEvent event) {
...
sched = schedFact.getScheduler();
sched.start();
JobDetail hourJob = newJob(HourJob.class ).withIdentity("hourJob", "group1").build();
Trigger hourTrig = newTrigger()
.withIdentity("hourTrig", "group1")
.withSchedule(cronSchedule("0 0 * * * ?")).build();
sched.scheduleJob(hourJob, hourTrig);
public void contextDestroyed(ServletContextEvent event) {
...
for(JobExecutionContext job : sched.getCurrentlyExecutingJobs()){
JobKey jK = job.getJobDetail().getKey();
System.out.printf("Inerrupting %s\n", jK.getName());
sched.interrupt(jK);
}
sched.shutdown(true);