Spring Scheduler定時任務 + Quartz
定時任務幾種實現方式
- Java自帶的java.util.Timer類,這個類允許你排程一個java.util.TimerTask任務,沒怎麼用過就不說了。
- Spring3.0以後自帶的task,可以將它看成一個輕量級的Quartz,而且使用起來比Quartz簡單許多。
- java的執行緒池類ScheduledExecutorService也可以實現一些簡單的定時任務,週期性任務。
- Quartz是一個功能比較強大的的排程器,可以讓你的程式在指定時間執行,也可以按照某一個頻度執行,可以方便的分散式部署、便捷的監控和管理任務,適合任務很多的情況。
Spring Scheduler註解方式實現
程式碼還是挺少的
@Component
public class SchedulerPractice{
// @Scheduled(fixedDelay=60000)
@Scheduled(cron = "0 0/1 * * * ?")
public void execute() {
logger.info("every one minute------");
}
}
配置檔案
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:task="http://www.springframework.org/schema/task"
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd
>
<context:annotation-config />
<!—spring掃描註解的配置 -->
<context:component-scan base-package="com.liu” />
<task:annotation-driven />
註解@Scheduled 中有三個方法,用來對執行規則的配置:
cron:指定cron表示式,文章最後有些配置示例。
fixedDelay:即表示從上一個任務完成開始到下一個任務開始的間隔,單位是毫秒。
fixedRate:即從上一個任務開始到下一個任務開始的間隔,單位是毫秒。
執行時間可配置化
將cron表示式配置在java的properties檔案或者環境變數中,是配置更靈活
xml配置方式
<task:scheduler id="myScheduler"/>
<task:scheduled-tasks scheduler="myScheduler" pool-size="2" />
<task:scheduled ref=“testScheduler” method="execute()” cron="${cron_expression}"/>
</task:scheduled-tasks>
pool-size=”2” 有多個任務可以配置以執行緒池執行
註解使用方式
@Scheduled(cron = "${cron_expression}")
分散式多例項執行
scheduler與web配置在一起,在高可用的情況下,如果有多個web容器例項,scheduler會在多個例項上同時執行。
解決辦法:
使用寫死伺服器Host的方式執行task,存在單點風險,負載均衡手動完成。(或者一臺程式碼中配置任務,其他不配置任務)
在task的基類加入一些邏輯,當開始執行時,將狀態(執行機器的IP、時間等)寫入資料庫、快取(redis)或者zk,執行結束時重置狀態。其它例項看到有這樣的資料,就直接返回。帶來的問題是:
一定要保證結束執行後將狀態重置,否則下一個執行週期,所有的task都會返回的。
因為讀寫狀態並非原子操作,偶爾也會發生task同時執行的事。使用zk分散式鎖,比如在任務執行方法上自定義註解,在註解中配置鎖在zk的路徑,在該註解上自定義個攔截器,在攔截器中獲取zk鎖。
Java執行緒池ScheduledExecutorService
示例程式碼如下
public void cronThread(){
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(1);
scheduledThreadPool.scheduleWithFixedDelay(new ThreadPractice(), 0, 3, TimeUnit.SECONDS);
}
new ThreadPractice()是一個實現了Runnable的類。
ScheduledExecutorService 類有兩個方法
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit)
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
long initialDelay,
long delay,
TimeUnit unit)
這兩個方法和@scheduled 註解中的fixedDelay和fixedRate類似。
Quartz
Quartz框架是一個全功能、開源的任務排程服務,可以整合幾乎任何的java應用程式—從小的微控制器系統到大型的電子商務系統。可以方便的分散式部署、便捷的監控和管理任務,Quartz可以執行上千上萬的任務排程。
核心概念
Quartz核心的概念:scheduler任務排程、Job任務、Trigger觸發器、JobDetail任務細節
Job任務:其實Job是介面,其中只有一個execute方法, 只要實現此介面,實現execute方法即可。
JobDetail:任務細節,Quartz執行Job時,需要新建個Job例項,但是不能直接操作Job類,所以通過JobDetail來獲取Job的名稱、描述資訊。
Trigger觸發器:執行任務的規則;比如每天,每小時等。觸發器有SimpleTrigger和CronTrigger,這個觸發器實現了Trigger介面。對於複雜的時間表示式來說,比如每個月15日上午幾點幾分,使用CronTrigger,對於簡單的時間來說,比如每天執行幾次,使用SimpleTrigger。
scheduler任務排程:是最核心的概念,需要把JobDetail和Trigger註冊到scheduler中,才可以執行。
quartz單機示例
使用的quartz的jar的版本是:2.2.1 ,低版本的核心類可能有些不同。
job類
public class MyJob implements Job {
@Override
//把要執行的操作,寫在execute方法中
public void execute(JobExecutionContext arg0) throws JobExecutionException {
System.out.println(“test Quartz"+new Date());
}
}
測試程式碼
@Test
public void startJobTest() {
SchedulerFactory schedulerfactory = new StdSchedulerFactory();
Scheduler scheduler = null;
try {
// 通過schedulerFactory獲取一個排程器
scheduler = schedulerfactory.getScheduler();
// 建立jobDetail例項,繫結Job實現類
// 指明job的名稱,所在組的名稱,以及繫結job類
JobDetail job = JobBuilder.newJob(ImageTableMonitorJob.class).withIdentity("job1", "jgroup1").build();
// 定義排程觸發規則
// 使用simpleTrigger規則
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("simpleTrigger", "triggerGroup")
.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(1).withRepeatCount(8)).startNow().build();
// 使用cornTrigger規則 每天10點42分
// Trigger trigger= TriggerBuilder.newTrigger().withIdentity("simpleTrigger", "triggerGroup")
// .withSchedule(CronScheduleBuilder.cronSchedule("0 42 10 * * ? *"))
// .startNow().build();
// 把作業和觸發器註冊到任務排程中
scheduler.scheduleJob(job, trigger);
// 啟動排程
scheduler.start();
} catch (Exception e) {
// e.printStackTrace();
}
}
spring提供了對quartz的整合,可以通過 org.springframework.scheduling.quartz.SchedulerFactoryBean
注入scheduler排程器,並且對排程器做些配置,比如使用執行緒池,並配置執行緒數量等。配置示例如下。
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" >
<property name="taskExecutor" ref="taskExecutor" />
<property name="autoStartup" value="false"/>
</bean>
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="2" />
<property name="maxPoolSize" value="512" />
</bean>
Quartz分散式原理
Quartz的叢集部署方案在架構上是分散式的,沒有負責集中管理的節點,而是利用資料庫鎖的方式來實現叢集環境下進行併發控制。分散式部署時需要保證各個節點的系統時間一致。沒弄過,就不細說了。
Quartz資料庫核心表QRTZ_LOCKS中有5條記錄CALENDAR_ACCESS,JOB_ACCESS,MISFIRE_ACCESS,STATE_ACCESS,TRIGGER_ACCESS 代表5把鎖,分別用於實現多個Quartz Node對Job、Trigger、Calendar訪問的同步控制。
cron表示式
欄位 允許值 允許的特殊字元
秒 0-59 , - * /
分 0-59 , - * /
小時 0-23 , - * /
日期 1-31 , - * ? / L W C
月份 1-12 或者 JAN-DEC , - * /
星期 1-7 或者 SUN-SAT , - * ? / L C #
年(可選) 留空, 1970-2099 , - * /
- 區間
* 萬用字元
? 你不想設定那個欄位
下面列出一些例項
CRON表示式 含義
"0 0 12 * * ?" 每天中午十二點觸發
"0 15 10 ? * *" 每天早上10:15觸發
"0 15 10 * * ?" 每天早上10:15觸發
"0 15 10 * * ? *" 每天早上10:15觸發
"0 15 10 * * ? 2005" 2005年的每天早上10:15觸發
"0 * 14 * * ?" 每天從下午2點開始到2點59分每分鐘一次觸發
"0 0/5 14 * * ?" 每天從下午2點開始到2:55分結束每5分鐘一次觸發
"0 0/5 14,18 * * ?" 每天的下午2點至2:55和6點至6點55分兩個時間段內每5分鐘一次觸發
"0 0-5 14 * * ?" 每天14:00至14:05每分鐘一次觸發
"0 10,44 14 ? 3 WED" 三月的每週三的14:10和14:44觸發
"0 15 10 ? * MON-FRI" 每個週一、週二、週三、週四、週五的10:15觸發
參考資料
相關文章
- Spring Boot 配置 Quartz 定時任務Spring Bootquartz
- 定時任務scheduler
- Spring+quartz 實現定時任務Springquartz
- 石英定時任務-quartzquartz
- Quartz - Spring整合Quartz實現叢集的定時任務quartzSpring
- spring2.0 quartz 靜態定時任務Springquartz
- quartz定時任務時間設定quartz
- Quartz 定時任務管理類quartz
- Quartz定時任務框架(二) Quartz詳解quartz框架
- 使用Spring整合Quartz輕鬆完成定時任務Springquartz
- Spring 整合 Quartz 實現動態定時任務Springquartz
- 一看便知spring+quartz定時任務Springquartz
- Oracle定時任務dbms_schedulerOracle
- java Quartz 定時任務管理類Javaquartz
- 初識spring與quartz整合實現定時任務Springquartz
- Spring+quartz實現動態化定時任務 (轉)Springquartz
- Quartz高可用定時任務快速上手quartz
- 普通web整合quartz跑定時任務Webquartz
- Quartz實現動態定時任務quartz
- SpringBoot整合Quartz定時任務Spring Bootquartz
- 淺談分散式定時任務之quartz分散式quartz
- springboot Quartz 定時任務工具類Spring Bootquartz
- Quartz定時任務框架(一) 入門案例quartz框架
- Spring 定時任務Spring
- Spring Boot整合quartz實現定時任務並支援切換任務資料來源Spring Bootquartz
- 簡單說說Java 定時任務框架---QuartzJava框架quartz
- quartz學習-quartz編碼方式實現定時任務簡例quartz
- Spring - Task定時任務Spring
- spring boot 定時任務Spring Boot
- java 定時任務 quartz 時間表示式Cron總結Javaquartz
- spring-boot-route(二十一)quartz實現動態定時任務Springbootquartz
- Grails整合Quartz外掛實現定時任務(Job)AIquartz
- NET作業排程(定時任務)-Quartz.Netquartz
- spring定時任務註解Spring
- Spring Boot(九):定時任務Spring Boot
- spring定時任務相關Spring
- spring執行定時任務Spring
- Spring Quartz定時器&n…Springquartz定時器