7
Schedule
Calvin edited this page 2013-11-14 01:37:15 +08:00
This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

##Ovewview 对于固定时间间隔的任务,JDK自带的Executor已足够好。

简单的Cron式定时任务,Spring自带的Scheduler也能执行,不再一定需要quartz了。

Spring的Scheduler模块还有schedule-task的namespace,可以不需更改任何代码,快速配置Timer/Cron式任务的执行,唯一缺陷是在JVM退出时只有简单的shutdown()或shutdownNow(),没有超时控制。另外任务调用时用的是反射。

至于Spring的annotation式配置任务,感觉是严重的白费力了,配置总是要摆在xml里的。

Quartz更大的优势体现在保证集群中有且仅有一台服务器执行了任务,而且用JDBC持久化任务,保证任务不会被漏掉。

SpringSide里还基于Redis实现了一种定时任务,有海量的一次性定时任务,每个任务在集群里只被执行一次,需要整个集群参与处理任务。此时Quartz的JDBC的性能无法支撑。

##Showcase中的演示 Showcase中演示了所有的技术选型:

###1. JDK Timer JdkTimerJob既是任务配置者,也同时是Runnable执行者。
在@PostConstruct中配置并启动任务,使用了Guava的ThreadFactoryBuilder配置任务线程的命名,使用了Spring的 TaskUtils.decorateTaskWithErrorHandler(this)方法,保证任务在异常时不会被打断。
在@PreDestroy时关闭任务线程。使用了自己封装的Threads.normalShutdown()控制超时。

以上三点都是直接用JDK Timer时需要注意的地方!!!

###2. Spring Cron SpringCronJob既是任务配置者,也同时是Runnable执行者。
在@PostConstruct中使用了Spring的ThreadPoolTaskScheduler和CronTrigger,配置cron任务并指定线程命名。 在@PreDestroy时同样使用自己封装的Threads.normalShutdown()关闭线程且控制超时。

###3. Spring Task Scheduler XML applicationContext-spring-scheduler.xml, 无需任何java代码,直接配置任务,用反射来调用执行。与前两种相比,只是少了系统shutdown时的超时控制。

###4. Quartz任务 Quartz任务有Timer和Cron,有单独执行和集群执行,有反射调用与继承于QuartzJobBean几种不同,分别在QuartzClusterableJob, applicationContext-quartz-cron-local.xml和applicationContext-quartz-timer-cluster.xml 中做了演示。

其中最特别是Cluster模式下,任务类本身也要持久化到数据库里,要求任务类及其属性都是可持久化的,像XXService这种属性就不能有了,需要用applicationContext,在需要的时候再动态取出。

##升级Quart2.1与Spring3.1+ Quartz2.1的API让大家不再依赖Spring的封装也能在applicationContext-*.xml中配置任务了。如果要继续用,那些JobDetailBean,MethodInvokingJobDetailBean,SimpleTriggerBean和CronTriggerBean 统统在"Bean"前面加上"Factory",比如CronTriggerFactoryBean.

最后升级一下数据库(如果有集群的,用jdbc持久化的话)