Skip to content
项目
群组
代码片段
帮助
正在加载...
登录
切换导航
X
XXL-JOB
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
靳帅
XXL-JOB
Commits
328f98a2
提交
328f98a2
authored
12月 01, 2015
作者:
xueli.xue
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
init
上级
08950b0b
隐藏空白字符变更
内嵌
并排
正在显示
12 个修改的文件
包含
386 行增加
和
9 行删除
+386
-9
README.md
README.md
+5
-2
Test.java
xxl-job-admin/src/test/java/Test.java
+65
-0
pom.xml
xxl-job-demo/pom.xml
+2
-0
DynamicSchedulerUtil.java
...mo/src/main/java/com/xxl/quartz/DynamicSchedulerUtil.java
+91
-0
JobModel.java
xxl-job-demo/src/main/java/com/xxl/quartz/JobModel.java
+78
-0
TriggerServiceImpl.java
...rc/main/java/com/xxl/service/impl/TriggerServiceImpl.java
+4
-6
JobDetailDemo.java
...demo/src/main/java/com/xxl/service/job/JobDetailDemo.java
+21
-0
applicationcontext-trigger-db.xml
...demo/src/main/resources/applicationcontext-trigger-db.xml
+47
-0
applicationcontext-trigger-local.xml
...o/src/main/resources/applicationcontext-trigger-local.xml
+1
-1
quartz.properties
xxl-job-demo/src/main/resources/quartz.properties
+24
-0
JunitTest.java
xxl-job-demo/src/test/java/quartz/JunitTest.java
+30
-0
TestDynamicJob.java
xxl-job-demo/src/test/java/quartz/TestDynamicJob.java
+18
-0
没有找到文件。
README.md
浏览文件 @
328f98a2
# xxl-job
任务调度框架xxl-job
# 任务调度框架xxl-job
Scheduler
Trigger
JobDetail
xxl-job-admin/src/test/java/Test.java
0 → 100644
浏览文件 @
328f98a2
import
java.util.Date
;
import
java.util.Timer
;
import
org.apache.commons.lang.time.FastDateFormat
;
public
class
Test
{
static
class
DemoTimeTask
extends
java
.
util
.
TimerTask
{
public
void
run
()
{
System
.
out
.
println
(
"run:"
+
FastDateFormat
.
getInstance
(
"yyyy-MM-dd HH:mm:ss"
).
format
(
new
Date
()));
}
}
// ??? 某一个时间段内,重复执行
// runTime:第一次执行时间
// delay: 延迟执行的毫秒数,即在delay毫秒之后第一次执行
// period:重复执行的时间间隔
public
static
Timer
mainTimer
;
public
static
void
main
(
String
[]
args
)
{
// 调度器
mainTimer
=
new
Timer
();
// Demo任务
DemoTimeTask
timeTask
=
new
DemoTimeTask
();
System
.
out
.
println
(
"now:"
+
FastDateFormat
.
getInstance
(
"yyyy-MM-dd HH:mm:ss"
).
format
(
new
Date
()));
// 1、在特定时间执行任务,只执行一次
//Date runTime = DateUtils.addSeconds(new Date(), 1);
//mainTimer.schedule(timeTask, runTime); // runTime
// 2、在特定时间之后执行任务,只执行一次
//long delay = 1000;
//mainTimer.schedule(timeTask, delay); // delay/ms
// 3、指定第一次执行的时间,然后按照间隔时间,重复执行
//Date firstTime = DateUtils.addSeconds(new Date(), 1);
//long period = 1000;
//mainTimer.schedule(timeTask, firstTime, period); // "period/ms" after "firstTime"
// 4、在特定延迟之后第一次执行,然后按照间隔时间,重复执行
//long delay = 1000;
//long period = 1000;
//mainTimer.schedule(timeTask, delay, period); // "period/ms" after "delay/ms"
// 5、第一次执行之后,特定频率执行,与3同
//Date firstTime = DateUtils.addSeconds(new Date(), 1);
//long period = 1000;
//mainTimer.scheduleAtFixedRate(timeTask, firstTime, period);
// 6、在delay毫秒之后第一次执行,后按照特定频率执行
long
delay
=
1000
;
long
period
=
1000
;
mainTimer
.
scheduleAtFixedRate
(
timeTask
,
delay
,
period
);
/**
* <1>schedule()方法更注重保持间隔时间的稳定:保障每隔period时间可调用一次
* <2>scheduleAtFixedRate()方法更注重保持执行频率的稳定:保障多次调用的频率趋近于period时间,如果任务执行时间大于period,会在任务执行之后马上执行下一次任务
*/
// Timer注销
mainTimer
.
cancel
();
}
}
xxl-job-demo/pom.xml
浏览文件 @
328f98a2
...
...
@@ -135,6 +135,8 @@
<version>
0.0.1-SNAPSHOT
</version>
</dependency>
</dependencies>
<build>
...
...
xxl-job-demo/src/main/java/com/xxl/quartz/DynamicSchedulerUtil.java
0 → 100644
浏览文件 @
328f98a2
package
com
.
xxl
.
quartz
;
import
org.quartz.*
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.InitializingBean
;
import
org.springframework.util.Assert
;
import
java.util.Date
;
public
final
class
DynamicSchedulerUtil
implements
InitializingBean
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
DynamicSchedulerUtil
.
class
);
// Scheduler
private
static
Scheduler
scheduler
;
public
static
void
setScheduler
(
Scheduler
scheduler
)
{
DynamicSchedulerUtil
.
scheduler
=
scheduler
;
}
@Override
public
void
afterPropertiesSet
()
throws
Exception
{
Assert
.
notNull
(
scheduler
,
"quartz scheduler is null"
);
logger
.
info
(
">>>>>>>>> init quartz scheduler success.[{}]"
,
scheduler
);
}
// Add 新增
public
static
boolean
addJob
(
JobModel
job
)
throws
SchedulerException
{
final
TriggerKey
triggerKey
=
job
.
getTriggerKey
();
if
(
scheduler
.
checkExists
(
triggerKey
))
{
final
Trigger
trigger
=
scheduler
.
getTrigger
(
triggerKey
);
logger
.
info
(
">>>>>>>>> Already exist trigger ["
+
trigger
+
"] by key ["
+
triggerKey
+
"] in Scheduler"
);
return
false
;
}
final
CronScheduleBuilder
cronScheduleBuilder
=
CronScheduleBuilder
.
cronSchedule
(
job
.
getCronExpression
());
final
CronTrigger
cronTrigger
=
TriggerBuilder
.
newTrigger
().
withIdentity
(
triggerKey
)
.
withSchedule
(
cronScheduleBuilder
)
.
build
();
final
JobDetail
jobDetail
=
job
.
getJobDetail
();
final
Date
date
=
scheduler
.
scheduleJob
(
jobDetail
,
cronTrigger
);
logger
.
debug
(
"Register DynamicJob {} on [{}]"
,
job
,
date
);
return
true
;
}
// Pause 暂停-指定Job
public
static
boolean
pauseJob
(
JobModel
existJob
)
throws
SchedulerException
{
final
TriggerKey
triggerKey
=
existJob
.
getTriggerKey
();
boolean
result
=
false
;
if
(
scheduler
.
checkExists
(
triggerKey
))
{
scheduler
.
pauseTrigger
(
triggerKey
);
result
=
true
;
logger
.
debug
(
"Pause exist DynamicJob {}, triggerKey [{}] successful"
,
existJob
,
triggerKey
);
}
else
{
logger
.
debug
(
"Failed pause exist DynamicJob {}, because not fount triggerKey [{}]"
,
existJob
,
triggerKey
);
}
return
result
;
}
// Resume 重启-指定Job
public
static
boolean
resumeJob
(
JobModel
existJob
)
throws
SchedulerException
{
final
TriggerKey
triggerKey
=
existJob
.
getTriggerKey
();
boolean
result
=
false
;
if
(
scheduler
.
checkExists
(
triggerKey
))
{
final
CronTrigger
newTrigger
=
existJob
.
cronTrigger
();
final
Date
date
=
scheduler
.
rescheduleJob
(
triggerKey
,
newTrigger
);
result
=
true
;
logger
.
debug
(
"Resume exist DynamicJob {}, triggerKey [{}] on [{}] successful"
,
existJob
,
triggerKey
,
date
);
}
else
{
logger
.
debug
(
"Failed resume exist DynamicJob {}, because not fount triggerKey [{}]"
,
existJob
,
triggerKey
);
}
return
result
;
}
// Remove exists job 移除-指定Job
public
static
boolean
removeJob
(
JobModel
existJob
)
throws
SchedulerException
{
final
TriggerKey
triggerKey
=
existJob
.
getTriggerKey
();
boolean
result
=
false
;
if
(
scheduler
.
checkExists
(
triggerKey
))
{
result
=
scheduler
.
unscheduleJob
(
triggerKey
);
}
logger
.
debug
(
"Remove DynamicJob {} result [{}]"
,
existJob
,
result
);
return
result
;
}
}
\ No newline at end of file
xxl-job-demo/src/main/java/com/xxl/quartz/JobModel.java
0 → 100644
浏览文件 @
328f98a2
package
com
.
xxl
.
quartz
;
import
org.quartz.CronScheduleBuilder
;
import
org.quartz.CronTrigger
;
import
org.quartz.Job
;
import
org.quartz.JobBuilder
;
import
org.quartz.JobDataMap
;
import
org.quartz.JobDetail
;
import
org.quartz.Scheduler
;
import
org.quartz.TriggerBuilder
;
import
org.quartz.TriggerKey
;
/**
* 任务model
* @author xuxueli 2015-12-1 16:01:19
*/
public
class
JobModel
{
// param
private
String
group
;
private
String
name
;
private
String
cronExpression
;
private
Class
<?
extends
Job
>
jobClass
;
public
JobModel
(
String
name
,
String
cronExpression
,
Class
<?
extends
Job
>
jobClass
)
{
this
.
group
=
Scheduler
.
DEFAULT_GROUP
;
this
.
name
=
name
;
this
.
cronExpression
=
cronExpression
;
this
.
jobClass
=
jobClass
;
}
public
String
getGroup
()
{
return
group
;
}
public
void
setGroup
(
String
group
)
{
this
.
group
=
group
;
}
public
String
getName
()
{
return
name
;
}
public
void
setName
(
String
name
)
{
this
.
name
=
name
;
}
public
String
getCronExpression
()
{
return
cronExpression
;
}
public
void
setCronExpression
(
String
cronExpression
)
{
this
.
cronExpression
=
cronExpression
;
}
public
Class
<?
extends
Job
>
getJobClass
()
{
return
jobClass
;
}
public
void
setJobClass
(
Class
<?
extends
Job
>
jobClass
)
{
this
.
jobClass
=
jobClass
;
}
// TriggerKey
public
TriggerKey
getTriggerKey
()
{
return
TriggerKey
.
triggerKey
(
this
.
name
,
this
.
group
);
}
// JobDetail
public
JobDetail
getJobDetail
()
{
return
JobBuilder
.
newJob
(
jobClass
).
withIdentity
(
this
.
name
,
this
.
group
).
build
();
}
// JobDataMap.add
public
JobModel
addJobData
(
String
key
,
Object
value
)
{
JobDataMap
jobDataMap
=
this
.
getJobDetail
().
getJobDataMap
();
jobDataMap
.
put
(
key
,
value
);
return
this
;
}
// CronTrigger
public
CronTrigger
cronTrigger
()
{
CronScheduleBuilder
cronScheduleBuilder
=
CronScheduleBuilder
.
cronSchedule
(
this
.
cronExpression
);
return
TriggerBuilder
.
newTrigger
().
withIdentity
(
this
.
getTriggerKey
()).
withSchedule
(
cronScheduleBuilder
).
build
();
}
}
\ No newline at end of file
xxl-job-demo/src/main/java/com/xxl/service/impl/TriggerServiceImpl.java
浏览文件 @
328f98a2
package
com
.
xxl
.
service
.
impl
;
import
java.util.Date
;
import
org.apache.commons.lang.time.FastDateFormat
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.stereotype.Service
;
...
...
@@ -19,12 +22,7 @@ public class TriggerServiceImpl implements ITriggerService {
* 全站静态化
*/
public
void
generateNetHtml
()
{
long
start
=
System
.
currentTimeMillis
();
logger
.
info
(
"全站静态化... start:{}"
,
start
);
long
end
=
System
.
currentTimeMillis
();
logger
.
info
(
"全站静态化... end:{}, cost:{}"
,
end
,
end
-
start
);
logger
.
info
(
"全站静态化 run at :{}"
,
FastDateFormat
.
getInstance
(
"yyyy-MM-dd HH:mm:ss"
).
format
(
new
Date
()));
}
}
xxl-job-demo/src/main/java/com/xxl/service/job/JobDetailDemo.java
0 → 100644
浏览文件 @
328f98a2
package
com
.
xxl
.
service
.
job
;
import
java.util.Date
;
import
org.apache.commons.lang.time.FastDateFormat
;
import
org.quartz.JobExecutionContext
;
import
org.quartz.JobExecutionException
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.scheduling.quartz.QuartzJobBean
;
public
class
JobDetailDemo
extends
QuartzJobBean
{
private
static
Logger
logger
=
LoggerFactory
.
getLogger
(
JobDetailDemo
.
class
);
@Override
protected
void
executeInternal
(
JobExecutionContext
context
)
throws
JobExecutionException
{
logger
.
info
(
"全站静态化[DB] run at :{}"
,
FastDateFormat
.
getInstance
(
"yyyy-MM-dd HH:mm:ss"
).
format
(
new
Date
()));
}
}
xxl-job-demo/src/main/resources/applicationcontext-trigger-db.xml
0 → 100644
浏览文件 @
328f98a2
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns=
"http://www.springframework.org/schema/beans"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:context=
"http://www.springframework.org/schema/context"
xmlns:util=
"http://www.springframework.org/schema/util"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd"
>
<!-- Job trigger -->
<bean
id=
"job02Trigger"
class=
"org.springframework.scheduling.quartz.CronTriggerFactoryBean"
>
<property
name=
"jobDetail"
>
<bean
class=
"org.springframework.scheduling.quartz.JobDetailFactoryBean"
>
<property
name=
"jobClass"
value=
"com.xxl.service.job.JobDetailDemo"
/>
<property
name=
"jobDataAsMap"
>
<map>
<!-- <entry key="xxService" value-ref="xxService" /> -->
</map>
</property>
<property
name=
"durability"
value=
"true"
/>
</bean>
</property>
<property
name=
"cronExpression"
value=
"0/3 * * * * ? *"
/>
</bean>
<!-- Job信息会被上报并持久化到mysql中,多个集群节点中竞争Job锁,只会有一台执行 -->
<bean
id=
"quartzScheduler"
lazy-init=
"false"
class=
"org.springframework.scheduling.quartz.SchedulerFactoryBean"
>
<property
name=
"dataSource"
ref=
"dataSource"
/>
<property
name=
"autoStartup"
value=
"true"
/>
<property
name=
"applicationContextSchedulerContextKey"
value=
"applicationContextKey"
/>
<property
name=
"configLocation"
value=
"classpath:quartz.properties"
/>
<property
name=
"triggers"
>
<list>
<!-- <ref bean="job02Trigger" /> -->
</list>
</property>
</bean>
<!-- 调度器 -->
<bean
id=
"dynamicSchedulerUtil"
class=
"com.xxl.quartz.DynamicSchedulerUtil"
>
<property
name=
"scheduler"
ref=
"quartzScheduler"
/>
</bean>
</beans>
\ No newline at end of file
xxl-job-demo/src/main/resources/applicationcontext-trigger.xml
→
xxl-job-demo/src/main/resources/applicationcontext-trigger
-local
.xml
浏览文件 @
328f98a2
...
...
@@ -22,7 +22,7 @@
<property
name=
"cronExpression"
value=
"0/3 * * * * ? *"
/>
</bean>
<!--
启动触发器的配置开始
-->
<!--
Job被加载到内存中,每个集群节点相互独立,都会执行该任务
-->
<bean
name=
"startQuertz"
lazy-init=
"false"
autowire=
"no"
class=
"org.springframework.scheduling.quartz.SchedulerFactoryBean"
>
<property
name=
"triggers"
>
<list>
...
...
xxl-job-demo/src/main/resources/quartz.properties
0 → 100644
浏览文件 @
328f98a2
# Default Properties file for use by StdSchedulerFactory
# to create a Quartz Scheduler Instance, if a different
# properties file is not explicitly specified.
#
org.quartz.scheduler.instanceName
:
DefaultQuartzScheduler
org.quartz.scheduler.rmi.export
:
false
org.quartz.scheduler.rmi.proxy
:
false
org.quartz.scheduler.wrapJobExecutionInUserTransaction
:
false
org.quartz.threadPool.class
:
org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount
:
10
org.quartz.threadPool.threadPriority
:
5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread
:
true
org.quartz.jobStore.misfireThreshold
:
60000
#org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore
# for cluster
org.quartz.scheduler.instanceId
:
AUTO
org.quartz.jobStore.class
:
org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.isClustered
:
true
org.quartz.jobStore.clusterCheckinInterval
:
1000
xxl-job-demo/src/test/java/quartz/JunitTest.java
0 → 100644
浏览文件 @
328f98a2
package
quartz
;
import
java.lang.reflect.InvocationTargetException
;
import
java.util.concurrent.TimeUnit
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.quartz.SchedulerException
;
import
org.springframework.test.context.ContextConfiguration
;
import
org.springframework.test.context.junit4.SpringJUnit4ClassRunner
;
import
com.xxl.quartz.DynamicSchedulerUtil
;
import
com.xxl.quartz.JobModel
;
@RunWith
(
SpringJUnit4ClassRunner
.
class
)
@ContextConfiguration
(
locations
=
"classpath*:applicationcontext-*.xml"
)
public
class
JunitTest
{
@Test
public
void
addJob
()
throws
SchedulerException
,
IllegalAccessException
,
InvocationTargetException
,
NoSuchMethodException
,
InterruptedException
{
boolean
ret
=
DynamicSchedulerUtil
.
addJob
(
new
JobModel
(
"Jost-job"
,
"0/1 * * * * ?"
,
TestDynamicJob
.
class
));
System
.
out
.
println
(
ret
);
TimeUnit
.
SECONDS
.
sleep
(
30
);
}
}
xxl-job-demo/src/test/java/quartz/TestDynamicJob.java
0 → 100644
浏览文件 @
328f98a2
package
quartz
;
import
org.quartz.Job
;
import
org.quartz.JobExecutionContext
;
import
org.quartz.JobExecutionException
;
import
java.util.Date
;
public
class
TestDynamicJob
implements
Job
{
@Override
public
void
execute
(
JobExecutionContext
context
)
throws
JobExecutionException
{
final
Object
mailGuid
=
context
.
getMergedJobDataMap
().
get
(
"mailGuid"
);
System
.
out
.
println
(
"[Dynamic-Job] It is "
+
new
Date
()
+
" now, mailGuid="
+
mailGuid
);
}
}
\ No newline at end of file
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论