xueli.xue 9 years ago
parent 9a5b01ed39
commit 23423855fc

@ -5,7 +5,25 @@ git.osc地址http://git.oschina.net/xuxueli0323/xxl-job
博客地址(内附使用教程)http://www.cnblogs.com/xuxueli/p/5021979.html 博客地址(内附使用教程)http://www.cnblogs.com/xuxueli/p/5021979.html
# 基于quartz封装实现的的集群任务调度管理平台 # 特点基于quartz封装实现的的集群任务调度管理平台
1、简单支持通过Web页面对任务进行CRUD操作操作简单一分钟上手 1、简单支持通过Web页面对任务进行CRUD操作操作简单一分钟上手
2、动态支持动态修改任务状态动态暂停/恢复任务,即时生效. 2、动态支持动态修改任务状态动态暂停/恢复任务,即时生效;
3、集群任务信息持久化到mysql中支持Job服务器集群(高可用),一个任务只会在其中一台服务器上执行 3、服务HA任务信息持久化到mysql中Job服务天然支持集群保证服务HA
4、任务HA某台Job服务挂掉任务会平滑分配给其他的某一台存活服务即使所有服务挂掉重启时或补偿执行丢失任务
5、一个任务只会在其中一台服务器上执行
6、任务串行执行
7、支持任务执行日志
8、支持自定义参数
# 新版本 V1.2.x :架构模块化 【开发中...】
说明V1.2版本将系统架构按功能拆分为:
调度模块[xxl-job-admin]:负责管理调度信息,按照调度配置发出调度请求;
任务模块[xxl-job-client-demo]负责接收调度请求并执行任务逻辑任务模块可以方便的嵌入web项目可以参考此demo
通讯模块[xxl-job-client]:负责调度模块和任务模块之间的信息通讯;
优点:
解耦:任务模块提供任务接口,调度模块维护调度信息,业务相互独立;
高扩展性;
稳定性;
Tips如果您追求一个简单调度服务这里也提供了一个简洁分支[xxl-job-simple],它针对旧版调度框架做了细微完善;

@ -1,11 +0,0 @@
## dianping-job[任务调度平台]
分层: 调度和任务拆分, 支持动态扩充, 管理任务
1. 调度模块dianping-job-web, 维护任务的调度信息,负责定时/周期性的发出调度请求.
2. 任务模块dianping-job-client, 具体的任务逻辑,负责接收调度模块的调度请求,执行任务逻辑.
3. 通讯模块dianping-job-client, 负责调度模块和任务模块之间的通讯.
说明:
1. 调度模块集群部署[HA].
2. 任务串行执行.
3. 记录调度日系.

@ -1,10 +0,0 @@
log4j.rootLogger=info,console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d - dianping-job-client-demo - %p [%c] - <%m>%n
log4j.appender.logFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.logFile.File=${catalina.base}/logs/dianping-job-client-demo.log
log4j.appender.logFile.layout=org.apache.log4j.PatternLayout
log4j.appender.logFile.layout.ConversionPattern=%d - dianping-job-client-demo - %p [%c] - <%m>%n

@ -1,10 +0,0 @@
log4j.rootLogger=info,console,logFile
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d - dianping-job-web - %p [%c] - <%m>%n
log4j.appender.logFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.logFile.File=${catalina.base}/logs/dianping-job-web.log
log4j.appender.logFile.layout=org.apache.log4j.PatternLayout
log4j.appender.logFile.layout.ConversionPattern=%d - dianping-job-web - %p [%c] - <%m>%n

@ -1,76 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>调度中心</title>
<#import "/common/common.macro.ftl" as netCommon>
<@netCommon.commonStyle />
</head>
<body class="hold-transition skin-blue sidebar-mini">
<div class="wrapper">
<!-- header -->
<@netCommon.commonHeader />
<!-- left -->
<@netCommon.commonLeft />
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>使用教程<small>调度管理平台</small></h1>
<ol class="breadcrumb">
<li><a><i class="fa fa-dashboard"></i>调度中心</a></li>
<li class="active">使用教程</li>
</ol>
</section>
<!-- Main content -->
<section class="content">
<div class="callout callout-info">
<h4>简介DIANPING_CLOCK</h4>
<p>基于quartz封装实现的的集群任务调度管理平台.</p>
<p></p>
</div>
<div class="callout callout-default">
<h4>特点:</h4>
<p>1、简单支持通过Web页面对任务进行CRUD操作操作简单一分钟上手.</p>
<p>2、动态支持动态修改任务状态动态暂停/恢复任务,即时生效.</p>
<p>3、集群任务信息持久化到mysql中支持Job服务器集群(高可用),一个任务只会在其中一台服务器上执行.</p>
</div>
<div class="callout callout-default">
<h4>分层模型:</h4>
<p>1、基础基于quartz封装底层调度层通过CORN自定义任务执行周期最终执行自定义JobBean的execute方法如需多个任务需要开发多个JobBean实现.</p>
<p>2、分层上述基础调度模型存在一定局限调度层和任务层耦合当新任务上线势必影响任务的正常调度因此规划将调度系统分层为调度层 + 任务层 + 通讯层.</p>
<p>
<div class="row">
<div class="col-xs-offset-1 col-xs-11">
<p>》调度模块:维护任务的调度信息,负责定时/周期性的发出调度请求.</p>
<p>》任务模块:具体的任务逻辑,负责接收调度模块的调度请求,执行任务逻辑.</p>
<p>》通讯模块:负责调度模块和任务模块之间的通讯.</p>
<p>(总而言之,一条完整任务由 “调度信息” 和 “任务信息” 组成.)</p>
</div>
</div>
</p>
</div>
<div class="callout callout-default">
<h4>调度属性解析 : 发出HTTP调度请求</h4>
<p>1、调度Key【必填】调度信息的全局唯一标识.</p>
<p>2、调度Corn【必填】调度执行的时间表达式.</p>
<p>3、调度描述【必填】调度的简述.</p>
<p>4、调度URL【必填】调度执行时发出HTTP请求的目标URL地址.</p>
<p>5、+args【选填】调度执行时发出HTTP请求的附带的POST参数.</p>
</div>
</section>
<!-- /.content -->
</div>
<!-- /.content-wrapper -->
<!-- footer -->
<@netCommon.commonFooter />
<!-- control -->
<@netCommon.commonControl />
</div>
<@netCommon.commonScript />
</body>
</html>

@ -1,168 +0,0 @@
#
# Quartz seems to work best with the driver mm.mysql-2.0.7-bin.jar
#
# PLEASE consider using mysql with innodb tables to avoid locking issues
#
# In your Quartz properties file, you'll need to set
# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#
DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
DROP TABLE IF EXISTS QRTZ_LOCKS;
DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
DROP TABLE IF EXISTS QRTZ_CALENDARS;
CREATE TABLE QRTZ_JOB_DETAILS
(
SCHED_NAME VARCHAR(120) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
JOB_CLASS_NAME VARCHAR(250) NOT NULL,
IS_DURABLE VARCHAR(1) NOT NULL,
IS_NONCONCURRENT VARCHAR(1) NOT NULL,
IS_UPDATE_DATA VARCHAR(1) NOT NULL,
REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
);
CREATE TABLE QRTZ_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
NEXT_FIRE_TIME BIGINT(13) NULL,
PREV_FIRE_TIME BIGINT(13) NULL,
PRIORITY INTEGER NULL,
TRIGGER_STATE VARCHAR(16) NOT NULL,
TRIGGER_TYPE VARCHAR(8) NOT NULL,
START_TIME BIGINT(13) NOT NULL,
END_TIME BIGINT(13) NULL,
CALENDAR_NAME VARCHAR(200) NULL,
MISFIRE_INSTR SMALLINT(2) NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
);
CREATE TABLE QRTZ_SIMPLE_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
REPEAT_COUNT BIGINT(7) NOT NULL,
REPEAT_INTERVAL BIGINT(12) NOT NULL,
TIMES_TRIGGERED BIGINT(10) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE QRTZ_CRON_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
CRON_EXPRESSION VARCHAR(200) NOT NULL,
TIME_ZONE_ID VARCHAR(80),
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE QRTZ_SIMPROP_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
STR_PROP_1 VARCHAR(512) NULL,
STR_PROP_2 VARCHAR(512) NULL,
STR_PROP_3 VARCHAR(512) NULL,
INT_PROP_1 INT NULL,
INT_PROP_2 INT NULL,
LONG_PROP_1 BIGINT NULL,
LONG_PROP_2 BIGINT NULL,
DEC_PROP_1 NUMERIC(13,4) NULL,
DEC_PROP_2 NUMERIC(13,4) NULL,
BOOL_PROP_1 VARCHAR(1) NULL,
BOOL_PROP_2 VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE QRTZ_BLOB_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
BLOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE QRTZ_CALENDARS
(
SCHED_NAME VARCHAR(120) NOT NULL,
CALENDAR_NAME VARCHAR(200) NOT NULL,
CALENDAR BLOB NOT NULL,
PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
);
CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
);
CREATE TABLE QRTZ_FIRED_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
ENTRY_ID VARCHAR(95) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
FIRED_TIME BIGINT(13) NOT NULL,
SCHED_TIME BIGINT(13) NOT NULL,
PRIORITY INTEGER NOT NULL,
STATE VARCHAR(16) NOT NULL,
JOB_NAME VARCHAR(200) NULL,
JOB_GROUP VARCHAR(200) NULL,
IS_NONCONCURRENT VARCHAR(1) NULL,
REQUESTS_RECOVERY VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,ENTRY_ID)
);
CREATE TABLE QRTZ_SCHEDULER_STATE
(
SCHED_NAME VARCHAR(120) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
CHECKIN_INTERVAL BIGINT(13) NOT NULL,
PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
);
CREATE TABLE QRTZ_LOCKS
(
SCHED_NAME VARCHAR(120) NOT NULL,
LOCK_NAME VARCHAR(40) NOT NULL,
PRIMARY KEY (SCHED_NAME,LOCK_NAME)
);
commit;

@ -1,33 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.dianping</groupId>
<artifactId>dianping-job</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>dianping-job-web</module>
<module>dianping-job-client</module>
<module>dianping-job-client-demo</module>
</modules>
<dependencies>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<encoding>UTF8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -3,10 +3,13 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.xxl</groupId> <groupId>com.xxl</groupId>
<artifactId>xxl-job</artifactId> <artifactId>xxl-job</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>1.1.1-SNAPSHOT</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<modules> <modules>
<module>xxl-job-admin</module> <module>xxl-job-admin</module>
<module>xxl-job-client</module>
<module>xxl-job-client-demo</module>
<module>xxl-job-simple</module>
</modules> </modules>
<build> <build>

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

@ -0,0 +1 @@
/target/

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>xxl-job-admin</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.common.project.facet.core.builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.validation.validationbuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
</natures>
</projectDescription>

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/webapp"/>
<classpathentry excluding="**/*.min.js|**/node_modules/*|**/bower_components/*" kind="src" path="target/m2e-wtp/web-resources"/>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject">
<attributes>
<attribute name="hide" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
<classpathentry kind="output" path=""/>
</classpath>

@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF8

@ -0,0 +1,8 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.6

@ -0,0 +1,4 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
<wb-module deploy-name="xxl-job-admin">
<wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
<wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
<dependent-module archiveName="xxl-job-client-1.1.2-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/xxl-job-client/xxl-job-client">
<dependency-type>uses</dependency-type>
</dependent-module>
<property name="context-root" value="xxl-job-admin"/>
<property name="java-output-path" value="/xxl-job-admin/target/classes"/>
</wb-module>
</project-modules>

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<fixed facet="wst.jsdt.web"/>
<installed facet="java" version="1.6"/>
<installed facet="jst.web" version="2.5"/>
<installed facet="wst.jsdt.web" version="1.0"/>
</faceted-project>

@ -0,0 +1 @@
org.eclipse.wst.jsdt.launching.baseBrowserLibrary

@ -0,0 +1,2 @@
disabled=06target
eclipse.preferences.version=1

@ -4,9 +4,10 @@
<parent> <parent>
<groupId>com.xxl</groupId> <groupId>com.xxl</groupId>
<artifactId>xxl-job</artifactId> <artifactId>xxl-job</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>1.1.1-SNAPSHOT</version>
</parent> </parent>
<artifactId>xxl-job-admin</artifactId> <artifactId>xxl-job-admin</artifactId>
<version>1.1.2-SNAPSHOT</version>
<packaging>war</packaging> <packaging>war</packaging>
<properties> <properties>
@ -128,13 +129,20 @@
<artifactId>quartz</artifactId> <artifactId>quartz</artifactId>
<version>2.2.1</version> <version>2.2.1</version>
</dependency> </dependency>
<!-- xxl-mq-core
<!-- httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.6</version>
</dependency>
<!-- xxl-job-client -->
<dependency> <dependency>
<groupId>com.xxl</groupId> <groupId>com.xxl</groupId>
<artifactId>xxl-job-core</artifactId> <artifactId>xxl-job-client</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>1.1.2-SNAPSHOT</version>
</dependency> </dependency>
-->
</dependencies> </dependencies>

@ -1,4 +1,4 @@
package com.dianping.job.controller; package com.xxl.job.controller;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.HashMap; import java.util.HashMap;
@ -18,10 +18,10 @@ import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import com.dianping.job.client.handler.HandlerRepository; import com.xxl.job.client.handler.HandlerRepository;
import com.dianping.job.core.model.ReturnT; import com.xxl.job.core.model.ReturnT;
import com.dianping.job.core.util.DynamicSchedulerUtil; import com.xxl.job.core.util.DynamicSchedulerUtil;
import com.dianping.job.service.job.HttpJobBean; import com.xxl.job.service.job.HttpJobBean;
/** /**
* index controller * index controller

@ -1,4 +1,4 @@
package com.dianping.job.core.model; package com.xxl.job.core.model;
/** /**
* common return * common return

@ -1,12 +1,12 @@
package com.dianping.job.core.model; package com.xxl.job.core.model;
import java.util.Date; import java.util.Date;
/** /**
* dianping job log, used to track trigger process * xxl-job log, used to track trigger process
* @author xuxueli 2015-12-19 23:19:09 * @author xuxueli 2015-12-19 23:19:09
*/ */
public class DianpingJobLog { public class XxlJobLog {
private String jobTriggerUuid; private String jobTriggerUuid;
private String jobHandleName; private String jobHandleName;
@ -70,7 +70,7 @@ public class DianpingJobLog {
@Override @Override
public String toString() { public String toString() {
return "DianpingJobLog [jobTriggerUuid=" + jobTriggerUuid + ", jobHandleName=" + jobHandleName return "XxlJobLog [jobTriggerUuid=" + jobTriggerUuid + ", jobHandleName=" + jobHandleName
+ ", triggerTime=" + triggerTime + ", triggerStatus=" + triggerStatus + ", triggerDetailLog=" + ", triggerTime=" + triggerTime + ", triggerStatus=" + triggerStatus + ", triggerDetailLog="
+ triggerDetailLog + ", handleTime=" + handleTime + ", handleStatus=" + handleStatus + triggerDetailLog + ", handleTime=" + handleTime + ", handleStatus=" + handleStatus
+ ", handleDetailLog=" + handleDetailLog + "]"; + ", handleDetailLog=" + handleDetailLog + "]";

@ -1,4 +1,4 @@
package com.dianping.job.core.util; package com.xxl.job.core.util;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;

@ -1,4 +1,4 @@
package com.dianping.job.service; package com.xxl.job.service;
/** /**
* local trigger, only exists in local jvm * local trigger, only exists in local jvm

@ -1,10 +1,10 @@
package com.dianping.job.service.impl; package com.xxl.job.service.impl;
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;
import com.dianping.job.service.ITriggerService; import com.xxl.job.service.ITriggerService;
/** /**
* local trigger, only exists in local jvm * local trigger, only exists in local jvm
@ -15,7 +15,7 @@ public class TriggerServiceImpl implements ITriggerService {
private static transient Logger logger = LoggerFactory.getLogger(TriggerServiceImpl.class); private static transient Logger logger = LoggerFactory.getLogger(TriggerServiceImpl.class);
public void beat() { public void beat() {
logger.info(">>>>>>>>>>> dianping-clock beat success."); logger.info(">>>>>>>>>>> xxl-job beat success.");
} }
} }

@ -1,4 +1,4 @@
package com.dianping.job.service.job; package com.xxl.job.service.job;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
@ -27,10 +27,10 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.scheduling.quartz.QuartzJobBean; import org.springframework.scheduling.quartz.QuartzJobBean;
import com.dianping.job.client.handler.HandlerRepository; import com.xxl.job.client.handler.HandlerRepository;
import com.dianping.job.client.handler.IJobHandler.JobTriggerStatus; import com.xxl.job.client.handler.IJobHandler.JobTriggerStatus;
import com.dianping.job.core.model.DianpingJobLog; import com.xxl.job.core.model.XxlJobLog;
import com.dianping.job.core.util.DynamicSchedulerUtil; import com.xxl.job.core.util.DynamicSchedulerUtil;
/** /**
* http job bean * http job bean
@ -58,17 +58,17 @@ public class HttpJobBean extends QuartzJobBean {
String job_url = params.get(DynamicSchedulerUtil.job_url); String job_url = params.get(DynamicSchedulerUtil.job_url);
triggerPost(job_url, params); triggerPost(job_url, params);
logger.info(">>>>>>>>>>> dianping-clock run :jobId:{}, group:{}, jobDataMap:{}", logger.info(">>>>>>>>>>> xxl-job run :jobId:{}, group:{}, jobDataMap:{}",
new Object[]{triggerKey, triggerGroup, jobDataMap}); new Object[]{triggerKey, triggerGroup, jobDataMap});
} }
public static void triggerPost(String reqURL, Map<String, String> params){ public static void triggerPost(String reqURL, Map<String, String> params){
// save log // save log
DianpingJobLog jobLog = new DianpingJobLog(); XxlJobLog jobLog = new XxlJobLog();
jobLog.setJobTriggerUuid(UUID.randomUUID().toString()); jobLog.setJobTriggerUuid(UUID.randomUUID().toString());
jobLog.setJobHandleName(params.get(HandlerRepository.handleName)); jobLog.setJobHandleName(params.get(HandlerRepository.handleName));
jobLog.setTriggerTime(new Date()); jobLog.setTriggerTime(new Date());
logger.info(">>>>>>>>>>> dianping-clock trigger start :jobLog:{}", jobLog); logger.info(">>>>>>>>>>> xxl-job trigger start :jobLog:{}", jobLog);
// post // post
String responseContent = null; String responseContent = null;
@ -91,7 +91,7 @@ public class HttpJobBean extends QuartzJobBean {
responseContent = EntityUtils.toString(entity, "UTF-8"); responseContent = EntityUtils.toString(entity, "UTF-8");
EntityUtils.consume(entity); EntityUtils.consume(entity);
} }
logger.info(">>>>>>>>>>> dianping-clock trigger ing :jobLog:{}, response:{}, responseContent:{}", jobLog, response, responseContent); logger.info(">>>>>>>>>>> xxl-job trigger ing :jobLog:{}, response:{}, responseContent:{}", jobLog, response, responseContent);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@ -117,17 +117,17 @@ public class HttpJobBean extends QuartzJobBean {
jobLog.setTriggerDetailLog(jobLog.getTriggerDetailLog().substring(0, 1000)); jobLog.setTriggerDetailLog(jobLog.getTriggerDetailLog().substring(0, 1000));
} }
logger.info(">>>>>>>>>>> dianping-clock trigger end :jobLog:{}", jobLog); logger.info(">>>>>>>>>>> xxl-job trigger end :jobLog:{}", jobLog);
} }
} }
public static void main(String[] args) { public static void main(String[] args) {
String url = "http://localhost:8080/dianping-job-client-demo/dianpingJobServlet"; String url = "http://localhost:8080/xxl-job-client-demo/xxlJobServlet";
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
Map<String, String> params = new HashMap<String, String>(); Map<String, String> params = new HashMap<String, String>();
params.put(HandlerRepository.handleName, "com.dianping.job.service.handler.DemoJobHandler"); params.put(HandlerRepository.handleName, "com.xxl.job.service.handler.DemoJobHandler");
params.put(HandlerRepository.triggerUuid, i+""); params.put(HandlerRepository.triggerUuid, i+"");
params.put("key", i+""); params.put("key", i+"");

@ -10,7 +10,7 @@
http://www.springframework.org/schema/util/spring-util.xsd"> http://www.springframework.org/schema/util/spring-util.xsd">
<context:annotation-config /> <context:annotation-config />
<context:component-scan base-package="com.xxl.service.impl, com.xxl.dao.impl" /> <context:component-scan base-package="com.xxl.job.service" />
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"> <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/template/" /> <property name="templateLoaderPath" value="/WEB-INF/template/" />
@ -19,11 +19,6 @@
<property name="location" value="classpath:freemarker.properties" /> <property name="location" value="classpath:freemarker.properties" />
</bean> </bean>
</property> </property>
<property name="freemarkerVariables">
<bean class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="classpath:freemarker.variables.properties" />
</bean>
</property>
</bean> </bean>
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

@ -15,7 +15,6 @@
<context:annotation-config /> <context:annotation-config />
<context:component-scan base-package="com.xxl.service.impl, com.xxl.dao.impl" /> <context:component-scan base-package="com.xxl.service.impl, com.xxl.dao.impl" />
<!-- c3p0Main数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${c3p0.driverClass}" /> <property name="driverClass" value="${c3p0.driverClass}" />
<property name="jdbcUrl" value="${c3p0.url}" /> <property name="jdbcUrl" value="${c3p0.url}" />
@ -35,7 +34,7 @@
<property name="mapperLocations" value="classpath*:com/xxl/core/model/mapper/*.xml"/> <property name="mapperLocations" value="classpath*:com/xxl/core/model/mapper/*.xml"/>
</bean> </bean>
<!-- Template在Junit测试的时候必须使用scope="prototype",原因未知 --> <!-- scope must be "prototype" when junit -->
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate" scope="prototype"> <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate" scope="prototype">
<constructor-arg index="0" ref="sqlSessionFactory" /> <constructor-arg index="0" ref="sqlSessionFactory" />
</bean> </bean>

@ -9,37 +9,16 @@
http://www.springframework.org/schema/util http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd"> 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"> <bean id="quartzScheduler" lazy-init="false" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="dataSource" ref="dataSource" /> <property name="dataSource" ref="dataSource" />
<property name="autoStartup" value="true" /> <property name="autoStartup" value="true" />
<property name="applicationContextSchedulerContextKey" value="applicationContextKey" /> <property name="applicationContextSchedulerContextKey" value="applicationContextKey" />
<property name="configLocation" value="classpath:quartz.properties"/> <property name="configLocation" value="classpath:quartz.properties"/>
<property name="triggers">
<list>
<!-- <ref bean="job02Trigger" /> -->
</list>
</property>
</bean> </bean>
<!-- 调度器 --> <!-- 协同-调度器 -->
<bean id="dynamicSchedulerUtil" class="com.xxl.quartz.DynamicSchedulerUtil"> <bean id="dynamicSchedulerUtil" class="com.xxl.job.core.util.DynamicSchedulerUtil">
<!-- (轻易不要变更“调度器名称”, 任务创建时会绑定该“调度器名称”) -->
<property name="scheduler" ref="quartzScheduler"/> <property name="scheduler" ref="quartzScheduler"/>
</bean> </bean>

@ -20,11 +20,11 @@
<property name="cronExpression" value="0/10 * * * * ? *" /> <property name="cronExpression" value="0/10 * * * * ? *" />
</bean> </bean>
<!-- Job被加载到内存中每个集群节点相互独立都会执行该任务 --> <!-- 进程-调度器 -->
<bean name="startQuertz" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <bean name="jvmQuertz" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers"> <property name="triggers">
<list> <list>
<ref bean="beatTrigger" /> <!-- <ref bean="beatTrigger" /> -->
</list> </list>
</property> </property>
</bean> </bean>

@ -12,15 +12,12 @@
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<!-- 事务管理器(声明式事务) -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" /> <property name="dataSource" ref="dataSource" />
</bean> </bean>
<!-- 启动事务注解方式1注解方式 -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/> <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
<!-- 事务通知方式2XML事务管理 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes> <tx:attributes>
<tx:method name="detail*" propagation="SUPPORTS" /> <tx:method name="detail*" propagation="SUPPORTS" />
@ -33,11 +30,8 @@
</tx:attributes> </tx:attributes>
</tx:advice> </tx:advice>
<!-- AOP配置 -->
<aop:config> <aop:config>
<!-- 定义一个切入点 -->
<aop:pointcut id="txoperation" expression="execution(* com.xxl.service.imp.*.*(..))" /> <aop:pointcut id="txoperation" expression="execution(* com.xxl.service.imp.*.*(..))" />
<!-- 切入点事务通知 -->
<aop:advisor pointcut-ref="txoperation" advice-ref="txAdvice" /> <aop:advisor pointcut-ref="txoperation" advice-ref="txAdvice" />
</aop:config> </aop:config>

@ -1,10 +1,10 @@
log4j.rootLogger=info,console log4j.rootLogger=info,console,logFile
log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d - xxl-job-demo - %p [%c] - <%m>%n log4j.appender.console.layout.ConversionPattern=%d - xxl-job-admin - %p [%c] - <%m>%n
log4j.appender.logFile=org.apache.log4j.DailyRollingFileAppender log4j.appender.logFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.logFile.File=${catalina.base}/logs/xxl-job-demo.log log4j.appender.logFile.File=${catalina.base}/logs/xxl-job-admin.log
log4j.appender.logFile.layout=org.apache.log4j.PatternLayout log4j.appender.logFile.layout=org.apache.log4j.PatternLayout
log4j.appender.logFile.layout.ConversionPattern=%d - xxl-job-demo - %p [%c] - <%m>%n log4j.appender.logFile.layout.ConversionPattern=%d - xxl-job-admin - %p [%c] - <%m>%n

@ -18,6 +18,7 @@ org.quartz.jobStore.misfireThreshold: 60000
#org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore #org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore
# for cluster # for cluster
#org.quartz.jobStore.tablePrefix = WED_qrtz_
org.quartz.scheduler.instanceId: AUTO org.quartz.scheduler.instanceId: AUTO
org.quartz.jobStore.class: org.quartz.impl.jdbcjobstore.JobStoreTX org.quartz.jobStore.class: org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.isClustered: true org.quartz.jobStore.isClustered: true

@ -18,34 +18,35 @@
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<description>Spring-web MVC配置</description>
<mvc:annotation-driven /> <mvc:annotation-driven />
<context:component-scan base-package="com.xxl.controller" /> <context:component-scan base-package="com.xxl.job.controller" />
<mvc:resources mapping="/favicon.ico" location="/favicon.ico" /> <mvc:resources mapping="/favicon.ico" location="/favicon.ico" />
<mvc:resources mapping="/static/**" location="/static/" /> <!-- 不拦截static目录下 --> <mvc:resources mapping="/static/**" location="/static/" />
<mvc:resources mapping="/**/*.html" location="/" /> <!-- 不拦截.html后缀 --> <mvc:resources mapping="/**/*.html" location="/" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver"> <bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView" /> <!-- 解析视图模板类 --> <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView" />
<property name="prefix" value="" /> <!-- 模板前后缀指定html页面为模板 --> <property name="prefix" value="" />
<property name="suffix" value=".ftl" /> <property name="suffix" value=".ftl" />
<property name="contentType" value="text/html;charset=UTF-8" /> <!-- 模板输出内容编码 (此处应与defaultEncoding保持一致) --> <property name="contentType" value="text/html;charset=UTF-8" />
<property name="exposeSpringMacroHelpers" value="true" /> <!-- 访问Request/Session宏助手 --> <property name="exposeSpringMacroHelpers" value="true" />
<property name="exposeRequestAttributes" value="true" /> <!-- 允许访问Request属性默认为false --> <property name="exposeRequestAttributes" value="true" />
<property name="exposeSessionAttributes" value="true" /> <!-- 允许访问Session属性默认为false --> <property name="exposeSessionAttributes" value="true" />
<property name="requestContextAttribute" value="request" /> <!-- 将HttpServletRequest的属性存放到request这个变量中 --> <property name="requestContextAttribute" value="request" />
<property name="cache" value="true" /> <property name="cache" value="true" />
<property name="order" value="0" /> <property name="order" value="0" />
</bean> </bean>
<!-- <mvc:interceptors> <!--
// 自定义拦截器支持SSO登陆拦截
<mvc:interceptors>
<mvc:interceptor> <mvc:interceptor>
<mvc:mapping path="/**"/> <mvc:mapping path="/**"/>
<bean class="com.xxl.controller.interceptor.PermissionInterceptor"/> <bean class="com.xxl.controller.interceptor.PermissionInterceptor"/>
</mvc:interceptor> </mvc:interceptor>
</mvc:interceptors> </mvc:interceptors>
<bean id="exceptionResolver" class="com.xxl.controller.resolver.WebExceptionResolver" /> --> <bean id="exceptionResolver" class="com.xxl.controller.resolver.WebExceptionResolver" />
-->
</beans> </beans>

@ -37,8 +37,6 @@
<script src="${request.contextPath}/static/adminlte/plugins/fastclick/fastclick.js"></script> <script src="${request.contextPath}/static/adminlte/plugins/fastclick/fastclick.js"></script>
<!-- AdminLTE App --> <!-- AdminLTE App -->
<script src="${request.contextPath}/static/adminlte/dist/js/app.min.js"></script> <script src="${request.contextPath}/static/adminlte/dist/js/app.min.js"></script>
<!-- SlimScroll 1.3.0 -->
<script src="${request.contextPath}/static/adminlte/plugins/slimScroll/jquery.slimscroll.min.js"></script>
<!-- scrollup --> <!-- scrollup -->
<script src="${request.contextPath}/static/plugins/scrollup/jquery.scrollUp.min.js"></script> <script src="${request.contextPath}/static/plugins/scrollup/jquery.scrollUp.min.js"></script>
@ -47,81 +45,15 @@
<#macro commonHeader> <#macro commonHeader>
<header class="main-header"> <header class="main-header">
<a href="${request.contextPath}/" class="logo">
<!-- Logo --> <span class="logo-mini"><b>X</b>XL</span>
<a href="${request.contextPath}/" class="logo"> <!-- mini logo for sidebar mini 50x50 pixels --> <span class="logo-lg"><b>任务调度</b>中心</span>
<span class="logo-mini"><b>X</b>XL</span> <!-- logo for regular state and mobile devices -->
<span class="logo-lg"><b>调度</b>中心</span>
</a> </a>
<!-- Header Navbar: style can be found in header.less -->
<nav class="navbar navbar-static-top" role="navigation"> <nav class="navbar navbar-static-top" role="navigation">
<!-- Sidebar toggle button-->
<a href="#" class="sidebar-toggle" data-toggle="offcanvas" role="button"><span class="sr-only">切换导航</span></a> <a href="#" class="sidebar-toggle" data-toggle="offcanvas" role="button"><span class="sr-only">切换导航</span></a>
<!-- Navbar Right Menu --> <div class="navbar-custom-menu"></div>
<div class="navbar-custom-menu">
<ul class="nav navbar-nav">
<!-- 通知: style can be found in dropdown.less -->
<li class="dropdown notifications-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-bell-o"></i> <span class="label label-warning">5</span></a>
<ul class="dropdown-menu">
<li class="header">您有5条通知</li>
<li>
<!-- inner menu: contains the actual data -->
<ul class="menu">
<li><a href="#"> <i class="fa fa-warning text-yellow"></i>
这是一个不错的应用
</a></li>
<li><a href="#"> <i class="fa fa-warning text-yellow"></i>
这是一个很不错的应用
</a></li>
<li><a href="#"> <i class="fa fa-warning text-yellow"></i>
这是一个非常不错的应用
</a></li>
<li><a href="#"> <i class="fa fa-warning text-yellow"></i>
这是一个非常非常不错的应用
</a></li>
<li><a href="#"> <i class="fa fa-warning text-yellow"></i>
这是一个非常非常非常不错的应用
</a></li>
</ul>
</li>
<li class="footer"><a href="#">查看全部</a></li>
</ul>
</li>
<!-- 账号: style can be found in dropdown.less -->
<li class="dropdown user user-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-user text-aqua"></i><span class="hidden-xs">${loginIdentity.userName}</span>
</a>
<ul class="dropdown-menu">
<!-- User image -->
<li class="user-header">
<p>
${loginIdentity.realName} - 前端研发
<small>注册于 2012-11-20</small>
</p>
</li>
<!-- Menu Body
<li class="user-body">
<div class="col-xs-4 text-center"><a href="#">Followers</a></div>
<div class="col-xs-4 text-center"><a href="#">Sales</a></div>
<div class="col-xs-4 text-center"><a href="#">Friends</a></div>
</li>-->
<!-- Menu Footer-->
<li class="user-footer">
<div class="pull-left"><a href="#" class="btn btn-default btn-flat">资料</a></div>
<div class="pull-right"><a href="javascript:;" class="btn btn-default btn-flat" id="logoutBtn" >注销</a></div>
</li>
</ul></li>
<!-- Control Sidebar Toggle Button -->
<li><a href="#" data-toggle="control-sidebar"><i class="fa fa-gears"></i></a></li>
</ul>
</div>
</nav> </nav>
</header> </header>
</#macro> </#macro>
<#macro commonLeft> <#macro commonLeft>
@ -131,20 +63,9 @@
<section class="sidebar"> <section class="sidebar">
<!-- sidebar menu: : style can be found in sidebar.less --> <!-- sidebar menu: : style can be found in sidebar.less -->
<ul class="sidebar-menu"> <ul class="sidebar-menu">
<li class="header">常用模块</li> <li class="header">常用模块</li>
<li class="nav-click" ><a href="${request.contextPath}/job/index"><i class="fa fa-circle-o text-red"></i> <span>调度管理</span></a></li> <li class="nav-click" ><a href="${request.contextPath}//"><i class="fa fa-circle-o text-red"></i> <span>调度中心</span></a></li>
<li class="nav-click" ><a href="${request.contextPath}/job/help"><i class="fa fa-circle-o text-yellow"></i><span>使用教程</span></a></li> <li class="nav-click" ><a href="${request.contextPath}/help"><i class="fa fa-circle-o text-yellow"></i><span>使用教程</span></a></li>
<li class="header">全部模块</li>
<li class="treeview nav-click">
<a href="#"><i class="fa fa-dashboard"></i> <span>调度中心</span><i class="fa fa-angle-left pull-right"></i></a>
<ul class="treeview-menu">
<li class="nav-click" ><a href="${request.contextPath}/job/index"><i class="fa fa-circle-o"></i>调度管理</a></li>
<li class="nav-click" ><a href="${request.contextPath}/job/help"><i class="fa fa-circle-o"></i>使用教程</a></li>
</ul>
</li>
</ul> </ul>
</section> </section>
<!-- /.sidebar --> <!-- /.sidebar -->
@ -234,8 +155,8 @@
<b>Version</b> 1.0 <b>Version</b> 1.0
</div> </div>
<strong>Copyright &copy; 2015-2015 &nbsp; <strong>Copyright &copy; 2015-2015 &nbsp;
<a href="https://github.com/xuxueli/" target="_blank" >github</a>&nbsp; <a href="https://github.com/xuxueli/xxl-job" target="_blank" >github</a>&nbsp;
<a href="http://www.cnblogs.com/xuxueli/" target="_blank" >cnblog</a>. <a href="http://www.cnblogs.com/xuxueli/p/5021979.html" target="_blank" >cnblog</a>.
</strong> All rights reserved. </strong> All rights reserved.
</footer> </footer>
</#macro> </#macro>

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>AdminLTE 2 | Dashboard</title> <title>调度中心</title>
<#import "/common/common.macro.ftl" as netCommon> <#import "/common/common.macro.ftl" as netCommon>
<@netCommon.commonStyle /> <@netCommon.commonStyle />
</head> </head>
@ -26,18 +26,41 @@
<!-- Main content --> <!-- Main content -->
<section class="content"> <section class="content">
<div class="callout callout-info"> <div class="callout callout-info">
<h4>简介:xxl-job</h4> <h4>简介:XXL_JOB</h4>
<p>调度管理平台:基于quartz封装实现的的集群任务调度管理平台.</p> <p>基于quartz封装实现的的集群任务调度管理平台.</p>
<p></p> <p></p>
</div> </div>
<div class="callout callout-default">
<div class="callout callout-info">
<h4>特点:</h4> <h4>特点:</h4>
<p>1、简单支持通过Web页面对任务进行CRUD操作操作简单一分钟上手.</p> <p>1、简单支持通过Web页面对任务进行CRUD操作操作简单一分钟上手.</p>
<p>2、动态支持动态修改任务状态动态暂停/恢复任务,即时生效.</p> <p>2、动态支持动态修改任务状态动态暂停/恢复任务,即时生效.</p>
<p>3、集群任务信息持久化到mysql中支持Job服务器集群(高可用),一个任务只会在其中一台服务器上执行.</p> <p>3、集群任务信息持久化到mysql中支持Job服务器集群(高可用),一个任务只会在其中一台服务器上执行.</p>
</div> </div>
<div class="callout callout-default">
<h4>分层模型:</h4>
<p>1、基础基于quartz封装底层调度层通过CORN自定义任务执行周期最终执行自定义JobBean的execute方法如需多个任务需要开发多个JobBean实现.</p>
<p>2、分层上述基础调度模型存在一定局限调度层和任务层耦合当新任务上线势必影响任务的正常调度因此规划将调度系统分层为调度层 + 任务层 + 通讯层.</p>
<p>
<div class="row">
<div class="col-xs-offset-1 col-xs-11">
<p>》调度模块:维护任务的调度信息,负责定时/周期性的发出调度请求.</p>
<p>》任务模块:具体的任务逻辑,负责接收调度模块的调度请求,执行任务逻辑.</p>
<p>》通讯模块:负责调度模块和任务模块之间的通讯.</p>
<p>(总而言之,一条完整任务由 “调度信息” 和 “任务信息” 组成.)</p>
</div>
</div>
</p>
</div>
<div class="callout callout-default">
<h4>调度属性解析 : 发出HTTP调度请求</h4>
<p>1、调度Key【必填】调度信息的全局唯一标识.</p>
<p>2、调度Corn【必填】调度执行的时间表达式.</p>
<p>3、调度描述【必填】调度的简述.</p>
<p>4、调度URL【必填】调度执行时发出HTTP请求的目标URL地址.</p>
<p>5、+args【选填】调度执行时发出HTTP请求的附带的POST参数.</p>
</div>
</section> </section>
<!-- /.content --> <!-- /.content -->
</div> </div>

@ -19,10 +19,10 @@
<div class="content-wrapper"> <div class="content-wrapper">
<!-- Content Header (Page header) --> <!-- Content Header (Page header) -->
<section class="content-header"> <section class="content-header">
<h1>使用教程<small>调度管理平台</small></h1> <h1>调度中心<small>调度管理</small></h1>
<ol class="breadcrumb"> <ol class="breadcrumb">
<li><a><i class="fa fa-dashboard"></i>调度中心</a></li> <li><a><i class="fa fa-dashboard"></i>调度中心</a></li>
<li class="active">使用教程</li> <li class="active">调度管理</li>
</ol> </ol>
</section> </section>
@ -32,17 +32,17 @@
<div class="col-xs-12"> <div class="col-xs-12">
<div class="box"> <div class="box">
<div class="box-header"> <div class="box-header">
<h3 class="box-title">任务列表</h3> <h3 class="box-title">调度列表</h3>
<button class="btn btn-primary btn-xs add" type="button">新增</button> <button class="btn btn-info btn-xs add" type="button">+新增任务</button>
</div> </div>
<div class="box-body"> <div class="box-body">
<table id="job_list" class="table table-bordered table-striped"> <table id="job_list" class="table table-bordered table-striped">
<thead> <thead>
<tr> <tr>
<th>任务ID</th> <th>调度key</th>
<th>cron</th> <th>cron</th>
<th>Job类路径</th> <!--<th>类路径</th>-->
<th>简介</th> <th>参数</th>
<th>状态</th> <th>状态</th>
<th>操作</th> <th>操作</th>
</tr> </tr>
@ -53,11 +53,13 @@
<tr> <tr>
<td>${item['TriggerKey'].name}</td> <td>${item['TriggerKey'].name}</td>
<td>${item['Trigger'].cronExpression}</td> <td>${item['Trigger'].cronExpression}</td>
<td>${item['JobDetail'].jobClass}</td> <!--<td>${item['JobDetail'].jobClass}</td>-->
<td> <td>
<#if item['JobDetail'].jobDataMap?exists> <#assign jobDataMap = item['JobDetail'].jobDataMap />
<#assign job_desc=item['JobDetail'].jobDataMap['job_desc'] /> <#if jobDataMap?exists && jobDataMap?keys?size gt 0>
${job_desc} <#list jobDataMap?keys as key>
${key} = ${jobDataMap[key]} <br>
</#list>
</#if> </#if>
</td> </td>
<td state="${item['TriggerState']}" > <td state="${item['TriggerState']}" >
@ -77,8 +79,9 @@
<#elseif item['TriggerState'] == 'PAUSED'> <#elseif item['TriggerState'] == 'PAUSED'>
<button class="btn btn-info btn-xs job_operate" type="job_resume" type="button">恢复</button> <button class="btn btn-info btn-xs job_operate" type="job_resume" type="button">恢复</button>
</#if> </#if>
<button class="btn btn-info btn-xs update" type="button">修改</button> <button class="btn btn-info btn-xs job_operate" type="job_trigger" type="button">执行一次</button>
<button class="btn btn-danger btn-xs job_operate" type="job_del" type="button">删除</button> <button class="btn btn-danger btn-xs job_operate" type="job_del" type="button">删除</button>
<button class="btn btn-info btn-xs update" type="button">更新corn</button>
</p> </p>
</td> </td>
</tr> </tr>
@ -87,10 +90,10 @@
</tbody> </tbody>
<tfoot> <tfoot>
<tr> <tr>
<th>任务ID</th> <th>调度key</th>
<th>cron</th> <th>cron</th>
<th>Job类路径</th> <!--<th>类路径</th>-->
<th>简介</th> <th>参数</th>
<th>状态</th> <th>状态</th>
<th>操作</th> <th>操作</th>
</tr> </tr>
@ -114,30 +117,35 @@
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h4 class="modal-title" >新增调度任务</h4> <h4 class="modal-title" >新增调度信息</h4>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<form class="form-horizontal form" role="form" > <form class="form-horizontal form" role="form" >
<div class="form-group"> <div class="form-group">
<label for="firstname" class="col-sm-2 control-label">任务Key</label> <label for="firstname" class="col-sm-3 control-label">任务Key</label>
<div class="col-sm-10"><input type="text" class="form-control" name="triggerKeyName" placeholder="请输入任务Key" minlength="4" maxlength="100" ></div> <div class="col-sm-9"><input type="text" class="form-control" name="triggerKeyName" placeholder="请输入任务Key" minlength="4" maxlength="100" ></div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="lastname" class="col-sm-2 control-label">任务Corn</label> <label for="lastname" class="col-sm-3 control-label">任务Corn</label>
<div class="col-sm-10"><input type="text" class="form-control" name="cronExpression" placeholder="请输入任务Corn[允许修改]" maxlength="100" ></div> <div class="col-sm-9"><input type="text" class="form-control" name="cronExpression" placeholder="请输入任务Corn[允许修改]" maxlength="100" ></div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="lastname" class="col-sm-2 control-label">任务Impl</label> <label for="lastname" class="col-sm-3 control-label">任务描述</label>
<div class="col-sm-10"><input type="text" class="form-control" name="jobClassName" placeholder="请输入任务Impl[不支持修改]" maxlength="100" ></div> <div class="col-sm-9"><input type="text" class="form-control" name="job_desc" placeholder="请输入任务描述[不支持修改]" maxlength="200" ></div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="lastname" class="col-sm-2 control-label">任务描述</label> <label for="lastname" class="col-sm-3 control-label">任务URL</label>
<div class="col-sm-10"><input type="text" class="form-control" name="jobDesc" placeholder="请输入任务描述[不支持修改]" maxlength="200" ></div> <div class="col-sm-9"><input type="text" class="form-control" name="job_url" placeholder="请输入任务URL[不支持修改]" maxlength="200" ></div>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="col-sm-offset-2 col-sm-10"> <label for="lastname" class="col-sm-3 control-label">任务handler</label>
<div class="col-sm-9"><input type="text" class="form-control" name="handleName" placeholder="请输入任务handler[不支持修改]" maxlength="200" ></div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-9">
<button type="submit" class="btn btn-primary" >保存</button> <button type="submit" class="btn btn-primary" >保存</button>
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button> <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-info pull-right addParam">+ arg</button>
</div> </div>
</div> </div>
</form> </form>
@ -151,7 +159,7 @@
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h4 class="modal-title" >更新配置</h4> <h4 class="modal-title" >更新corn</h4>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<form class="form-horizontal form" role="form" > <form class="form-horizontal form" role="form" >
@ -163,14 +171,6 @@
<label for="lastname" class="col-sm-2 control-label">任务Corn</label> <label for="lastname" class="col-sm-2 control-label">任务Corn</label>
<div class="col-sm-10"><input type="text" class="form-control" name="cronExpression" placeholder="请输入任务Corn" maxlength="100" ></div> <div class="col-sm-10"><input type="text" class="form-control" name="cronExpression" placeholder="请输入任务Corn" maxlength="100" ></div>
</div> </div>
<div class="form-group">
<label for="lastname" class="col-sm-2 control-label">任务Impl</label>
<div class="col-sm-10"><input type="text" class="form-control" name="jobClassName" placeholder="请输入任务Impl" maxlength="100" readonly ></div>
</div>
<div class="form-group">
<label for="lastname" class="col-sm-2 control-label">任务描述</label>
<div class="col-sm-10"><input type="text" class="form-control" name="jobDesc" placeholder="请输入任务描述" maxlength="200" readonly ></div>
</div>
<div class="form-group"> <div class="form-group">
<div class="col-sm-offset-2 col-sm-10"> <div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-primary" >保存</button> <button type="submit" class="btn btn-primary" >保存</button>

@ -4,6 +4,10 @@
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5"> id="WebApp_ID" version="2.5">
<display-name>xxl-job-admin</display-name> <display-name>xxl-job-admin</display-name>
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>xxl-job-admin</param-value>
</context-param>
<context-param> <context-param>
<param-name>contextConfigLocation</param-name> <param-name>contextConfigLocation</param-name>

@ -41,6 +41,9 @@ $(function() {
} else if ("job_del" == type) { } else if ("job_del" == type) {
typeName = "删除"; typeName = "删除";
url = base_url + "/job/remove"; url = base_url + "/job/remove";
} else if ("job_trigger" == type) {
typeName = "执行一次";
url = base_url + "/job/trigger";
} else { } else {
return; return;
} }
@ -70,9 +73,16 @@ $(function() {
}); });
}); });
// jquery.validate 自定义校验 “英文字母开头,只含有英文字母、数字和下划线”
jQuery.validator.addMethod("myValid01", function(value, element) {
var length = value.length;
var valid = /^[a-zA-Z][a-zA-Z0-9_]*$/;
return this.optional(element) || valid.test(value);
}, "只支持英文字母开头,只含有英文字母、数字和下划线");
// 新增 // 新增
$(".add").click(function(){ $(".add").click(function(){
$('#addModal').modal('show'); $('#addModal').modal({backdrop: false, keyboard: false}).modal('show');
}); });
var addModalValidate = $("#addModal .form").validate({ var addModalValidate = $("#addModal .form").validate({
errorElement : 'span', errorElement : 'span',
@ -82,17 +92,22 @@ $(function() {
triggerKeyName : { triggerKeyName : {
required : true , required : true ,
minlength: 4, minlength: 4,
maxlength: 100 maxlength: 100,
myValid01:true
}, },
cronExpression : { cronExpression : {
required : true , required : true ,
maxlength: 100 maxlength: 100
}, },
jobClassName : { job_desc : {
required : true , required : true ,
maxlength: 100 maxlength: 200
},
job_url : {
required : true ,
maxlength: 200
}, },
jobDesc : { handleName : {
required : true , required : true ,
maxlength: 200 maxlength: 200
} }
@ -100,20 +115,24 @@ $(function() {
messages : { messages : {
triggerKeyName : { triggerKeyName : {
required :"请输入“任务Key”." , required :"请输入“任务Key”." ,
minlength:"“任务Key”不应低于4位", minlength:"“任务Key”长度不应低于4位",
maxlength:"“任务Key”不应超过100位" maxlength:"“任务Key”长度不应超过100位"
}, },
cronExpression : { cronExpression : {
required :"请输入“任务Corn”." , required :"请输入“任务Corn”." ,
maxlength:"“任务Corn”不应超过100位" maxlength:"“任务Corn”长度不应超过100位"
}, },
jobClassName : { job_desc : {
required :"请输入“任务Impl”." ,
maxlength:"“任务Impl”不应超过100位"
},
jobDesc : {
required :"请输入“任务描述”." , required :"请输入“任务描述”." ,
maxlength:"“任务描述”不应超过200位" maxlength:"“任务描述”长度不应超过200位"
},
job_url : {
required :"请输入“任务URL”." ,
maxlength:"“任务URL”长度不应超过200位"
},
handleName : {
required : "请输入“任务handler”." ,
maxlength: "“任务handler”长度不应超过200位"
} }
}, },
highlight : function(element) { highlight : function(element) {
@ -127,7 +146,39 @@ $(function() {
element.parent('div').append(error); element.parent('div').append(error);
}, },
submitHandler : function(form) { submitHandler : function(form) {
$.post(base_url + "/job/add", $("#addModal .form").serialize(), function(data, status) {
var triggerKeyName = $('#addModal input[name="triggerKeyName"]').val();
var cronExpression = $('#addModal input[name="cronExpression"]').val();
var job_desc = $('#addModal input[name="job_desc"]').val();
var job_url = $('#addModal input[name="job_url"]').val();
var handleName = $('#addModal input[name="handleName"]').val();
var paramStr = 'triggerKeyName=' + triggerKeyName +
'&cronExpression=' + cronExpression +
'&job_desc=' + job_desc +
'&job_url=' + job_url +
'&handleName=' + handleName;
var ifFin = true;
$('#addModal .newParam').each(function(){
ifFin = false;
var key = $(this).find('input[name="key"]').val();
var value = $(this).find('input[name="value"]').val();
if (!key) {
ComAlert.show(2, "新增参数key不可为空");
return;
} else {
if(!/^[a-zA-Z][a-zA-Z0-9_]*$/.test(key)){
ComAlert.show(2, "新增参数key不合法, 只支持英文字母开头,只含有英文字母、数字和下划线");
return;
}
}
paramStr += "&" + key + "=" + value;
ifFin = true;
});
if(ifFin){
$.post(base_url + "/job/add", paramStr, function(data, status) {
if (data.code == "200") { if (data.code == "200") {
ComAlert.show(1, "新增调度任务成功", function(){ ComAlert.show(1, "新增调度任务成功", function(){
window.location.reload(); window.location.reload();
@ -141,18 +192,31 @@ $(function() {
} }
}); });
} }
}
}); });
$("#addModal").on('hide.bs.modal', function () { $("#addModal").on('hide.bs.modal', function () {
$("#addModal .form")[0].reset() $("#addModal .form")[0].reset()
}); });
// 新增-添加参数
$("#addModal .addParam").on('click', function () {
var html = '<div class="form-group newParam">'+
'<label for="lastname" class="col-sm-2 control-label">参数&nbsp;<button class="btn btn-danger btn-xs removeParam" type="button">移除</button></label>'+
'<div class="col-sm-4"><input type="text" class="form-control" name="key" placeholder="请输入参数key[将会强转为String]" maxlength="200" /></div>'+
'<div class="col-sm-6"><input type="text" class="form-control" name="value" placeholder="请输入参数value[将会强转为String]" maxlength="200" /></div>'+
'</div>';
$(this).parents('.form-group').parent().append(html);
$("#addModal .removeParam").on('click', function () {
$(this).parents('.form-group').remove();
});
});
// 更新 // 更新
$(".update").click(function(){ $(".update").click(function(){
$("#updateModal .form input[name='triggerKeyName']").val($(this).parent('p').attr("name")); $("#updateModal .form input[name='triggerKeyName']").val($(this).parent('p').attr("name"));
$("#updateModal .form input[name='cronExpression']").val($(this).parent('p').attr("cronExpression")); $("#updateModal .form input[name='cronExpression']").val($(this).parent('p').attr("cronExpression"));
$("#updateModal .form input[name='jobClassName']").val($(this).parent('p').attr("jobClassName")); $('#updateModal').modal({backdrop: false, keyboard: false}).modal('show');
$("#updateModal .form input[name='jobDesc']").val($(this).parent('p').attr("jobDesc"));
$('#updateModal').modal('show');
}); });
var updateModalValidate = $("#updateModal .form").validate({ var updateModalValidate = $("#updateModal .form").validate({
errorElement : 'span', errorElement : 'span',
@ -167,14 +231,6 @@ $(function() {
cronExpression : { cronExpression : {
required : true , required : true ,
maxlength: 100 maxlength: 100
},
jobClassName : {
required : true ,
maxlength: 100
},
jobDesc : {
required : true ,
maxlength: 200
} }
}, },
messages : { messages : {
@ -186,14 +242,6 @@ $(function() {
cronExpression : { cronExpression : {
required :"请输入“任务Corn”." , required :"请输入“任务Corn”." ,
maxlength:"“任务Corn”不应超过100位" maxlength:"“任务Corn”不应超过100位"
},
jobClassName : {
required :"请输入“任务Impl”." ,
maxlength:"“任务Impl”不应超过100位"
},
jobDesc : {
required :"请输入“任务描述”." ,
maxlength:"“任务描述”不应超过200位"
} }
}, },
highlight : function(element) { highlight : function(element) {

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

@ -0,0 +1 @@
/target/

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>xxl-job-client-demo</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.common.project.facet.core.builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.validation.validationbuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
</natures>
</projectDescription>

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/webapp"/>
<classpathentry excluding="**/*.min.js|**/node_modules/*|**/bower_components/*" kind="src" path="target/m2e-wtp/web-resources"/>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject">
<attributes>
<attribute name="hide" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
<classpathentry kind="output" path=""/>
</classpath>

@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF8

@ -0,0 +1,8 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.6

@ -0,0 +1,4 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
<wb-module deploy-name="xxl-job-client-demo">
<wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
<wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
<dependent-module archiveName="xxl-job-client-1.1.2-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/xxl-job-client/xxl-job-client">
<dependency-type>uses</dependency-type>
</dependent-module>
<property name="context-root" value="xxl-job-client-demo"/>
<property name="java-output-path" value="/xxl-job-client-demo/target/classes"/>
</wb-module>
</project-modules>

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<fixed facet="wst.jsdt.web"/>
<installed facet="java" version="1.6"/>
<installed facet="jst.web" version="2.5"/>
<installed facet="wst.jsdt.web" version="1.0"/>
</faceted-project>

@ -0,0 +1 @@
org.eclipse.wst.jsdt.launching.baseBrowserLibrary

@ -0,0 +1,2 @@
disabled=06target
eclipse.preferences.version=1

@ -2,14 +2,13 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>com.dianping</groupId> <groupId>com.xxl</groupId>
<artifactId>dianping-job</artifactId> <artifactId>xxl-job</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>1.1.1-SNAPSHOT</version>
</parent> </parent>
<artifactId>dianping-job-client-demo</artifactId> <artifactId>xxl-job-client-demo</artifactId>
<version>1.1.2-SNAPSHOT</version>
<packaging>war</packaging> <packaging>war</packaging>
<name>dianping-job-client-demo</name>
<url>http://maven.apache.org</url>
<properties> <properties>
<spring.version>3.2.14.RELEASE</spring.version> <spring.version>3.2.14.RELEASE</spring.version>
@ -52,11 +51,11 @@
<version>1.7.5</version> <version>1.7.5</version>
</dependency> </dependency>
<!-- dianping-job-client --> <!-- xxl-job-client -->
<dependency> <dependency>
<groupId>com.dianping</groupId> <groupId>com.xxl</groupId>
<artifactId>dianping-job-client</artifactId> <artifactId>xxl-job-client</artifactId>
<version>1.0.1-SNAPSHOT</version> <version>1.1.2-SNAPSHOT</version>
</dependency> </dependency>
</dependencies> </dependencies>

@ -1,4 +1,4 @@
package com.dianping.job.service.handler; package com.xxl.job.service.handler;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
@ -8,8 +8,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.dianping.job.client.handler.HandlerRepository; import com.xxl.job.client.handler.HandlerRepository;
import com.dianping.job.client.handler.IJobHandler; import com.xxl.job.client.handler.IJobHandler;
/** /**
* demo job handler * demo job handler

@ -9,7 +9,6 @@
http://www.springframework.org/schema/util http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd"> http://www.springframework.org/schema/util/spring-util.xsd">
<context:annotation-config /> <context:component-scan base-package="com.xxl.job.service" />
<context:component-scan base-package="com.dianping.job.service" />
</beans> </beans>

@ -0,0 +1,10 @@
log4j.rootLogger=info,console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d - xxl-job-client-demo - %p [%c] - <%m>%n
log4j.appender.logFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.logFile.File=${catalina.base}/logs/xxl-job-client-demo.log
log4j.appender.logFile.layout=org.apache.log4j.PatternLayout
log4j.appender.logFile.layout.ConversionPattern=%d - xxl-job-client-demo - %p [%c] - <%m>%n

@ -3,6 +3,10 @@
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5"> id="WebApp_ID" version="2.5">
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>xxl-job-client-demo</param-value>
</context-param>
<context-param> <context-param>
<param-name>contextConfigLocation</param-name> <param-name>contextConfigLocation</param-name>
@ -16,18 +20,17 @@
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> </listener>
<!-- Dianping Job Servlet --> <!-- Xxl Job Servlet -->
<servlet> <servlet>
<servlet-name>DianpingJobServlet</servlet-name> <servlet-name>XxlJobServlet</servlet-name>
<servlet-class>com.dianping.job.client.netcom.http.DianpingJobServlet</servlet-class> <servlet-class>com.xxl.job.client.netcom.http.XxlJobServlet</servlet-class>
<load-on-startup>1</load-on-startup> <load-on-startup>1</load-on-startup>
</servlet> </servlet>
<servlet-mapping> <servlet-mapping>
<servlet-name>DianpingJobServlet</servlet-name> <servlet-name>XxlJobServlet</servlet-name>
<url-pattern>/dianpingJobServlet</url-pattern> <url-pattern>/xxlJobServlet</url-pattern>
</servlet-mapping> </servlet-mapping>
<display-name>clock-job-web</display-name>
<welcome-file-list> <welcome-file-list>
<welcome-file>index.html</welcome-file> <welcome-file>index.html</welcome-file>
</welcome-file-list> </welcome-file-list>

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="org.eclipse.jst.component.nondependency" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

@ -0,0 +1 @@
/target/

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>xxl-job-client</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.wst.common.project.facet.core.builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.validation.validationbuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
</natures>
</projectDescription>

@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF8

@ -0,0 +1,8 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.6

@ -0,0 +1,4 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
<wb-module deploy-name="xxl-job-client">
<wb-resource deploy-path="/" source-path="/src/main/java"/>
</wb-module>
</project-modules>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<installed facet="java" version="1.6"/>
<installed facet="jst.utility" version="1.0"/>
</faceted-project>

@ -0,0 +1,2 @@
disabled=06target
eclipse.preferences.version=1

@ -2,14 +2,12 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>com.dianping</groupId> <groupId>com.xxl</groupId>
<artifactId>dianping-job</artifactId> <artifactId>xxl-job</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>1.1.1-SNAPSHOT</version>
</parent> </parent>
<artifactId>dianping-job-client</artifactId> <artifactId>xxl-job-client</artifactId>
<version>1.0.1-SNAPSHOT</version> <version>1.1.2-SNAPSHOT</version>
<name>dianping-job-client</name>
<url>http://maven.apache.org</url>
<dependencies> <dependencies>

@ -1,4 +1,4 @@
package com.dianping.job.client.handler; package com.xxl.job.client.handler;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
@ -10,8 +10,9 @@ import java.util.concurrent.TimeUnit;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.dianping.job.client.handler.IJobHandler.JobHandleStatus; import com.xxl.job.client.handler.IJobHandler.JobHandleStatus;
import com.dianping.job.client.handler.IJobHandler.JobTriggerStatus; import com.xxl.job.client.handler.IJobHandler.JobTriggerStatus;
/** /**
* handler repository * handler repository
@ -38,7 +39,7 @@ public class HandlerRepository {
HandlerThread handlerThread = new HandlerThread(handleName); HandlerThread handlerThread = new HandlerThread(handleName);
handlerThread.start(); handlerThread.start();
handlerTreadMap.put(handleName, handlerThread); handlerTreadMap.put(handleName, handlerThread);
logger.info(">>>>>>>>>>> dianping-job regist handler success, handleName:{}, handler:{}, handlerDateQueue:{}, handlerThread:{}", logger.info(">>>>>>>>>>> xxl-job regist handler success, handleName:{}, handler:{}, handlerDateQueue:{}, handlerThread:{}",
new Object[]{handleName, handler, handlerDateQueue, handlerThread}); new Object[]{handleName, handler, handlerDateQueue, handlerThread});
} }
@ -71,7 +72,7 @@ public class HandlerRepository {
jobHandleDetail = out.toString(); jobHandleDetail = out.toString();
} }
String _triggerUuid = handlerDate.get(triggerUuid); String _triggerUuid = handlerDate.get(triggerUuid);
logger.info("<<<<<<<<<<< dianping-job thread handle, _triggerUuid:{}, _handleName:{}, jobHandleStatus:{}, jobHandleDetail:{}, thread:{}", logger.info("<<<<<<<<<<< xxl-job thread handle, _triggerUuid:{}, _handleName:{}, jobHandleStatus:{}, jobHandleDetail:{}, thread:{}",
new Object[]{_triggerUuid, _handleName, jobHandleStatus, jobHandleDetail, this}); new Object[]{_triggerUuid, _handleName, jobHandleStatus, jobHandleDetail, this});
} else { } else {
try { try {
@ -98,7 +99,7 @@ public class HandlerRepository {
if (handlerDateQueue == null) { if (handlerDateQueue == null) {
handlerDateQueue = new LinkedBlockingQueue<Map<String, String>>(); handlerDateQueue = new LinkedBlockingQueue<Map<String, String>>();
handlerDataQueueMap.put(handleName, handlerDateQueue); handlerDataQueueMap.put(handleName, handlerDateQueue);
logger.info(">>>>>>>>>>> dianping-job handler lazy fresh handlerDateQueue, handleName:{}, handler:{}, handlerDateQueue:{}", logger.info(">>>>>>>>>>> xxl-job handler lazy fresh handlerDateQueue, handleName:{}, handler:{}, handlerDateQueue:{}",
new Object[]{handleName, handler, handlerDateQueue}); new Object[]{handleName, handler, handlerDateQueue});
} }
handlerDateQueue.offer(_param); handlerDateQueue.offer(_param);
@ -109,7 +110,7 @@ public class HandlerRepository {
HandlerThread handlerThread = new HandlerThread(handleName); HandlerThread handlerThread = new HandlerThread(handleName);
handlerThread.start(); handlerThread.start();
handlerTreadMap.put(handleName, handlerThread); handlerTreadMap.put(handleName, handlerThread);
logger.info(">>>>>>>>>>> dianping-job handler lazy fresh thread, handleName:{}, handler:{}, handlerThread:{}", logger.info(">>>>>>>>>>> xxl-job handler lazy fresh thread, handleName:{}, handler:{}, handlerThread:{}",
new Object[]{handleName, handler, handlerThread}); new Object[]{handleName, handler, handlerThread});
} }
_triggerStatus = JobTriggerStatus.SUCCESS; _triggerStatus = JobTriggerStatus.SUCCESS;
@ -122,7 +123,7 @@ public class HandlerRepository {
e.printStackTrace(new PrintWriter(out)); e.printStackTrace(new PrintWriter(out));
_triggerDetailLog = out.toString(); _triggerDetailLog = out.toString();
} }
logger.info(">>>>>>>>>>> dianping-job pushHandleQueue, triggerUuid:{}, handleName, _triggerStatus:{}, _triggerDetailLog", logger.info(">>>>>>>>>>> xxl-job pushHandleQueue, triggerUuid:{}, handleName, _triggerStatus:{}, _triggerDetailLog",
new Object[]{triggerUuid, handleName, _triggerStatus, _triggerDetailLog}); new Object[]{triggerUuid, handleName, _triggerStatus, _triggerDetailLog});
String responseBody = _triggerStatus.name(); String responseBody = _triggerStatus.name();

@ -1,4 +1,4 @@
package com.dianping.job.client.handler; package com.xxl.job.client.handler;
import java.util.Map; import java.util.Map;

@ -1,4 +1,4 @@
package com.dianping.job.client.netcom.http; package com.xxl.job.client.netcom.http;
import java.io.IOException; import java.io.IOException;
@ -10,19 +10,20 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import com.dianping.job.client.handler.HandlerRepository; import com.xxl.job.client.handler.HandlerRepository;
/** /**
* remote job client on http * remote job client on http
* @author xuxueli 2015-12-19 18:36:47 * @author xuxueli 2015-12-19 18:36:47
*/ */
public class DianpingJobServlet extends HttpServlet { public class XxlJobServlet extends HttpServlet {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** /**
* Default constructor. * Default constructor.
*/ */
public DianpingJobServlet() { public XxlJobServlet() {
// TODO Auto-generated constructor stub // TODO Auto-generated constructor stub
} }

@ -1,4 +1,4 @@
package com.dianping.job.client.util; package com.xxl.job.client.util;
import java.io.IOException; import java.io.IOException;

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

@ -0,0 +1 @@
/target/

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>xxl-job-simple</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.common.project.facet.core.builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.validation.validationbuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
</natures>
</projectDescription>

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/webapp"/>
<classpathentry excluding="**/*.min.js|**/node_modules/*|**/bower_components/*" kind="src" path="target/m2e-wtp/web-resources"/>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject">
<attributes>
<attribute name="hide" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
<classpathentry kind="output" path=""/>
</classpath>

@ -0,0 +1,3 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF8
encoding//src/test/java=UTF8

@ -0,0 +1,8 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.6

@ -0,0 +1,4 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
<wb-module deploy-name="xxl-job-simple">
<wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
<wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
<property name="context-root" value="xxl-job-simple"/>
<property name="java-output-path" value="/xxl-job-simple/target/classes"/>
</wb-module>
</project-modules>

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<fixed facet="wst.jsdt.web"/>
<installed facet="java" version="1.6"/>
<installed facet="jst.web" version="2.5"/>
<installed facet="wst.jsdt.web" version="1.0"/>
</faceted-project>

@ -0,0 +1 @@
org.eclipse.wst.jsdt.launching.baseBrowserLibrary

@ -0,0 +1,2 @@
disabled=06target
eclipse.preferences.version=1

@ -2,15 +2,13 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>com.dianping</groupId> <groupId>com.xxl</groupId>
<artifactId>dianping-job</artifactId> <artifactId>xxl-job</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>1.1.1-SNAPSHOT</version>
</parent> </parent>
<artifactId>dianping-job-web</artifactId> <artifactId>xxl-job-simple</artifactId>
<version>1.0.1-SNAPSHOT</version> <version>1.1.2-SNAPSHOT</version>
<packaging>war</packaging> <packaging>war</packaging>
<name>dianping-job-web</name>
<url>http://maven.apache.org</url>
<properties> <properties>
<spring.version>3.2.14.RELEASE</spring.version> <spring.version>3.2.14.RELEASE</spring.version>
@ -132,20 +130,6 @@
<version>2.2.1</version> <version>2.2.1</version>
</dependency> </dependency>
<!-- httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.6</version>
</dependency>
<!-- dianping-job-client -->
<dependency>
<groupId>com.dianping</groupId>
<artifactId>dianping-job-client</artifactId>
<version>1.0.1-SNAPSHOT</version>
</dependency>
</dependencies> </dependencies>
<build> <build>

@ -17,11 +17,10 @@ import com.xxl.quartz.DynamicSchedulerUtil;
import com.xxl.quartz.ReturnT; import com.xxl.quartz.ReturnT;
@Controller @Controller
@RequestMapping("/job")
public class IndexController { public class IndexController {
@RequestMapping("/index") @RequestMapping("")
public String index(Model model) { public String index(Model model) {
List<Map<String, Object>> jobList = DynamicSchedulerUtil.getJobList(); List<Map<String, Object>> jobList = DynamicSchedulerUtil.getJobList();
model.addAttribute("jobList", jobList); model.addAttribute("jobList", jobList);

@ -10,7 +10,7 @@
http://www.springframework.org/schema/util/spring-util.xsd"> http://www.springframework.org/schema/util/spring-util.xsd">
<context:annotation-config /> <context:annotation-config />
<context:component-scan base-package="com.dianping.job.service" /> <context:component-scan base-package="com.xxl.service.impl, com.xxl.dao.impl" />
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"> <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/template/" /> <property name="templateLoaderPath" value="/WEB-INF/template/" />
@ -19,6 +19,11 @@
<property name="location" value="classpath:freemarker.properties" /> <property name="location" value="classpath:freemarker.properties" />
</bean> </bean>
</property> </property>
<property name="freemarkerVariables">
<bean class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="classpath:freemarker.variables.properties" />
</bean>
</property>
</bean> </bean>
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

@ -15,6 +15,7 @@
<context:annotation-config /> <context:annotation-config />
<context:component-scan base-package="com.xxl.service.impl, com.xxl.dao.impl" /> <context:component-scan base-package="com.xxl.service.impl, com.xxl.dao.impl" />
<!-- c3p0Main数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${c3p0.driverClass}" /> <property name="driverClass" value="${c3p0.driverClass}" />
<property name="jdbcUrl" value="${c3p0.url}" /> <property name="jdbcUrl" value="${c3p0.url}" />
@ -34,7 +35,7 @@
<property name="mapperLocations" value="classpath*:com/xxl/core/model/mapper/*.xml"/> <property name="mapperLocations" value="classpath*:com/xxl/core/model/mapper/*.xml"/>
</bean> </bean>
<!-- scope must be "prototype" when junit --> <!-- Template在Junit测试的时候必须使用scope="prototype",原因未知 -->
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate" scope="prototype"> <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate" scope="prototype">
<constructor-arg index="0" ref="sqlSessionFactory" /> <constructor-arg index="0" ref="sqlSessionFactory" />
</bean> </bean>

@ -9,16 +9,37 @@
http://www.springframework.org/schema/util http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd"> 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"> <bean id="quartzScheduler" lazy-init="false" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="dataSource" ref="dataSource" /> <property name="dataSource" ref="dataSource" />
<property name="autoStartup" value="true" /> <property name="autoStartup" value="true" />
<property name="applicationContextSchedulerContextKey" value="applicationContextKey" /> <property name="applicationContextSchedulerContextKey" value="applicationContextKey" />
<property name="configLocation" value="classpath:quartz.properties"/> <property name="configLocation" value="classpath:quartz.properties"/>
<property name="triggers">
<list>
<!-- <ref bean="job02Trigger" /> -->
</list>
</property>
</bean> </bean>
<!-- 协同-调度器 --> <!-- 调度器 -->
<bean id="dynamicSchedulerUtil" class="com.dianping.job.core.util.DynamicSchedulerUtil"> <bean id="dynamicSchedulerUtil" class="com.xxl.quartz.DynamicSchedulerUtil">
<!-- (轻易不要变更“调度器名称”, 任务创建时会绑定该“调度器名称”) -->
<property name="scheduler" ref="quartzScheduler"/> <property name="scheduler" ref="quartzScheduler"/>
</bean> </bean>

@ -20,11 +20,11 @@
<property name="cronExpression" value="0/10 * * * * ? *" /> <property name="cronExpression" value="0/10 * * * * ? *" />
</bean> </bean>
<!-- 进程-调度器 --> <!-- Job被加载到内存中每个集群节点相互独立都会执行该任务 -->
<bean name="jvmQuertz" 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>
<!-- <ref bean="beatTrigger" /> --> <ref bean="beatTrigger" />
</list> </list>
</property> </property>
</bean> </bean>

@ -12,12 +12,15 @@
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<!-- 事务管理器(声明式事务) -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" /> <property name="dataSource" ref="dataSource" />
</bean> </bean>
<!-- 启动事务注解方式1注解方式 -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/> <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
<!-- 事务通知方式2XML事务管理 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes> <tx:attributes>
<tx:method name="detail*" propagation="SUPPORTS" /> <tx:method name="detail*" propagation="SUPPORTS" />
@ -30,8 +33,11 @@
</tx:attributes> </tx:attributes>
</tx:advice> </tx:advice>
<!-- AOP配置 -->
<aop:config> <aop:config>
<!-- 定义一个切入点 -->
<aop:pointcut id="txoperation" expression="execution(* com.xxl.service.imp.*.*(..))" /> <aop:pointcut id="txoperation" expression="execution(* com.xxl.service.imp.*.*(..))" />
<!-- 切入点事务通知 -->
<aop:advisor pointcut-ref="txoperation" advice-ref="txAdvice" /> <aop:advisor pointcut-ref="txoperation" advice-ref="txAdvice" />
</aop:config> </aop:config>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save