Quartz是一个Java调度框架,当前的最新版本为2.2.1。数据库
以Quartz 2.2.1版为例,Quartz最佳实践(用于生产系统)总结以下:
一、跳过更新检查
Quartz内置了一个“更新检查”特性,所以Quartz项目每次启动后都会检查官网,Quartz是否存在新版本。这个检查是异步的,不影响Quartz项目自己的启动和初始化。
能够在Quartz配置文件中,设置org.quartz.scheduler.skipUpdateCheck的属性为true来跳过更新检查。
二、JobDataMap技巧
在JobDataMap应该只存储原始的数据类型(包括字符串),这样能够避免数据序列化的问题以及长期运行的问题。
三、使用合并后的JobDataMap
官方推荐,Job.execute()方法一般应该从JobExecutionContext发现的JobDataMap中取回数据,而不是直接从JobDetail中取数据。
四、使用TriggerUtils
TriggerUtils工具类做用以下:
1)提供了一种更简单的建立触发器的方式;
2)提供了带调度器建立触发器的各类方法来知足特殊需求,与直接初始化特殊类型的触发器(SimpleTrigger、CronTrigger),而后调用各类setter方法进行配置相反。
3)提供了更为简单的建立日期时间的方法;
4)提供了辅助类来分析触发器(好比计算将来的激活次数等)。
五、必定不要直接写数据到Quartz表
经过SQL语句写调度数据到数据库表,而不该该使用调度API来写数据,由于:
1)会致使数据冲突(删除数据、争夺的数据)。
2)会致使当触发器的激活时间到了时,Job会看起来不见了。
3)会致使当触发器的激活时间到了时,Job会不执行,看起来“仅仅坐在那儿”。
4)可能会致使死锁
5)还可能致使其余奇怪的问题和数据崩溃等
六、必定不要把多个非集群的调度器实例指向同一个数据库表
若是把多个调度器实例指向同一个数据库表,并且这些调度器实例没有作集群配置,那么可能会发生:
1)会致使数据冲突(删除数据、争夺的数据)。
2)会致使当触发器的激活时间到了时,Job会看起来不见了。
3)会致使当触发器的激活时间到了时,Job会不执行,看起来“仅仅坐在那儿”。
4)可能会致使死锁
5)还可能致使其余奇怪的问题和数据崩溃等
七、确保适合的数据源链接数
官方推荐数据源的最大链接数应该配置为线程池的最小工做线程数的3倍。若是你还须要额外的链接(好比频繁地调用调度器API),若是还使用了JobStoreCMT,那么非托管的数据源的最大链接数应该是至少4倍以上。
八、避免调度Job的时间安排在夏令时转换的交界处
SimpleTrigger触发器不受此影响。
九、等待条件
若是链接池全部的线程都处于繁忙状态,那么长期运行的Job会阻止其余Job的运行。
若是在工做线程执行Job时调用Thread.sleep()后,Job余下的工做有可能得不到执行,由于会等待一些条件(好比数据记录有效后)为真后再执行。
最佳的解决方案是释放工做线程(退出Job),容许其余Job在线程上获得执行。Job能够从新调度自身,或者等其余Job在退出前调度它。
十、Job抛出异常
Job执行方法应该包含try-catch代码块,以处理各类可能发生的异常。
若是Job抛出异常,Quartz一般会当即从新执行(看起来会再次抛出一样的异常)。最佳的方式是让Job可以捕获它可能会遇到的全部异常,处理这些异常,而后再重调度Job。
十一、可恢复性和幂等性
标记为“可恢复的”、在进行中的Job在调度器失效后是能够自动从新执行的。这意味着一样的Job工做可能会执行两次。
十二、在监听器中保持代码简洁高效
不鼓励监听器内执行大量的工做,执行Job或完成触发器并激活另外一个Job等,都应该绑定到监听器。
1三、监听器抛出异常
每一个监听器(TriggerListener、JobListener和SchedulerListener)应该包含try-catch代码块,以处理各类可能发生的异常。
若是监听器抛出异常,它或许会致使其余监听器得不到通知或阻止Job的执行等等。
1四、注意安全
一些开发者会经过应用程序的用户接口暴露Quartz调度器的功能,这颇有用,但也很危险。由于恶意用户能够经过这种方式控制或破坏您的系统。安全