Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
熊鹏飞
/
xxljob220
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
328f98a2
authored
Dec 01, 2015
by
xueli.xue
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
init
parent
08950b0b
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
386 additions
and
9 deletions
README.md
xxl-job-admin/src/test/java/Test.java
xxl-job-demo/pom.xml
xxl-job-demo/src/main/java/com/xxl/quartz/DynamicSchedulerUtil.java
xxl-job-demo/src/main/java/com/xxl/quartz/JobModel.java
xxl-job-demo/src/main/java/com/xxl/service/impl/TriggerServiceImpl.java
xxl-job-demo/src/main/java/com/xxl/service/job/JobDetailDemo.java
xxl-job-demo/src/main/resources/applicationcontext-trigger-db.xml
xxl-job-demo/src/main/resources/applicationcontext-trigger.xml → xxl-job-demo/src/main/resources/applicationcontext-trigger-local.xml
xxl-job-demo/src/main/resources/quartz.properties
xxl-job-demo/src/test/java/quartz/JunitTest.java
xxl-job-demo/src/test/java/quartz/TestDynamicJob.java
README.md
View file @
328f98a2
# xxl-job
# 任务调度框架xxl-job
任务调度框架xxl-job
Scheduler
Trigger
JobDetail
xxl-job-admin/src/test/java/Test.java
0 → 100644
View file @
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
View file @
328f98a2
...
@@ -135,6 +135,8 @@
...
@@ -135,6 +135,8 @@
<version>
0.0.1-SNAPSHOT
</version>
<version>
0.0.1-SNAPSHOT
</version>
</dependency>
</dependency>
</dependencies>
</dependencies>
<build>
<build>
...
...
xxl-job-demo/src/main/java/com/xxl/quartz/DynamicSchedulerUtil.java
0 → 100644
View file @
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
View file @
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
View file @
328f98a2
package
com
.
xxl
.
service
.
impl
;
package
com
.
xxl
.
service
.
impl
;
import
java.util.Date
;
import
org.apache.commons.lang.time.FastDateFormat
;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
...
@@ -19,12 +22,7 @@ public class TriggerServiceImpl implements ITriggerService {
...
@@ -19,12 +22,7 @@ public class TriggerServiceImpl implements ITriggerService {
* 全站静态化
* 全站静态化
*/
*/
public
void
generateNetHtml
()
{
public
void
generateNetHtml
()
{
long
start
=
System
.
currentTimeMillis
();
logger
.
info
(
"全站静态化 run at :{}"
,
FastDateFormat
.
getInstance
(
"yyyy-MM-dd HH:mm:ss"
).
format
(
new
Date
()));
logger
.
info
(
"全站静态化... start:{}"
,
start
);
long
end
=
System
.
currentTimeMillis
();
logger
.
info
(
"全站静态化... end:{}, cost:{}"
,
end
,
end
-
start
);
}
}
}
}
xxl-job-demo/src/main/java/com/xxl/service/job/JobDetailDemo.java
0 → 100644
View file @
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
View file @
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
View file @
328f98a2
...
@@ -22,7 +22,7 @@
...
@@ -22,7 +22,7 @@
<property
name=
"cronExpression"
value=
"0/3 * * * * ? *"
/>
<property
name=
"cronExpression"
value=
"0/3 * * * * ? *"
/>
</bean>
</bean>
<!--
启动触发器的配置开始
-->
<!--
Job被加载到内存中,每个集群节点相互独立,都会执行该任务
-->
<bean
name=
"startQuertz"
lazy-init=
"false"
autowire=
"no"
class=
"org.springframework.scheduling.quartz.SchedulerFactoryBean"
>
<bean
name=
"startQuertz"
lazy-init=
"false"
autowire=
"no"
class=
"org.springframework.scheduling.quartz.SchedulerFactoryBean"
>
<property
name=
"triggers"
>
<property
name=
"triggers"
>
<list>
<list>
...
...
xxl-job-demo/src/main/resources/quartz.properties
0 → 100644
View file @
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
View file @
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
View file @
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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment