commit
3fda544884
|
@ -0,0 +1,11 @@
|
|||
Please answer some questions before submitting your issue. Thanks!
|
||||
|
||||
### Which version of XXL-JOB do you using?
|
||||
|
||||
### Expected behavior
|
||||
|
||||
### Actual behavior
|
||||
|
||||
### Steps to reproduce the behavior
|
||||
|
||||
### Other information
|
|
@ -0,0 +1,14 @@
|
|||
**What kind of change does this PR introduce?** (check at least one)
|
||||
|
||||
- [ ] Bugfix
|
||||
- [ ] Feature
|
||||
- [ ] Code style update
|
||||
- [ ] Refactor
|
||||
- [ ] Build-related changes
|
||||
- [ ] Other, please describe:
|
||||
|
||||
|
||||
**The description of the PR:**
|
||||
|
||||
|
||||
**Other information:**
|
111
README.md
111
README.md
|
@ -1,21 +1,48 @@
|
|||
<p align="center">
|
||||
<a href="http://www.xuxueli.com/">
|
||||
<img src="https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/xxl-logo.jpg" width="150">
|
||||
</a>
|
||||
<h3 align="center">XXL-JOB</h3>
|
||||
<p align="center">
|
||||
XXL-JOB, a lightweight distributed task scheduling framework.
|
||||
<br>
|
||||
<a href="http://www.xuxueli.com/"><strong>-- Browse xuxueli's website. --</strong></a>
|
||||
<br>
|
||||
<br>
|
||||
<a href="https://travis-ci.org/xuxueli/xxl-job">
|
||||
<img src="https://travis-ci.org/xuxueli/xxl-job.svg?branch=master" >
|
||||
</a>
|
||||
<a href="https://maven-badges.herokuapp.com/maven-central/com.xuxueli/xxl-job/">
|
||||
<img src="https://maven-badges.herokuapp.com/maven-central/com.xuxueli/xxl-job/badge.svg" >
|
||||
</a>
|
||||
<a href="https://github.com/xuxueli/xxl-job/releases">
|
||||
<img src="https://img.shields.io/github/release/xuxueli/xxl-job.svg" >
|
||||
</a>
|
||||
<a href="http://www.gnu.org/licenses/gpl-3.0.html">
|
||||
<img src="https://img.shields.io/badge/license-GPLv3-blue.svg" >
|
||||
</a>
|
||||
<a href="https://gitter.im/xuxueli/xxl-job?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge">
|
||||
<img src="https://badges.gitter.im/xuxueli/xxl-job.svg" >
|
||||
</a>
|
||||
</p>
|
||||
</p>
|
||||
|
||||
# 分布式任务调度平台XXL-JOB
|
||||
|
||||
[![Build Status](https://travis-ci.org/xuxueli/xxl-job.svg?branch=master)](https://travis-ci.org/xuxueli/xxl-job)
|
||||
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.xuxueli/xxl-job/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.xuxueli/xxl-job/)
|
||||
[![GitHub release](https://img.shields.io/github/release/xuxueli/xxl-job.svg)](https://github.com/xuxueli/xxl-job/releases)
|
||||
[![License](https://img.shields.io/badge/license-GPLv3-blue.svg)](http://www.gnu.org/licenses/gpl-3.0.html)
|
||||
[![Gitter](https://badges.gitter.im/xuxueli/xxl-job.svg)](https://gitter.im/xuxueli/xxl-job?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
## Intro
|
||||
XXL-JOB is a lightweight distributed task scheduling framework.
|
||||
It's core design goal is to develop quickly and learn simple, lightweight, and easy to expand.
|
||||
Now, it's already open source, and many companies use it in production environments, real "out-of-the-box".
|
||||
|
||||
XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。
|
||||
|
||||
![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/xxl-logo.jpg "在这里输入图片标题")
|
||||
|
||||
### 文档
|
||||
## Documentation
|
||||
|
||||
- 官方文档:[XXL-JOB官方文档](https://github.com/xuxueli/xxl-job/blob/master/doc/XXL-JOB官方文档.md)
|
||||
- [中文文档](https://github.com/xuxueli/xxl-job/blob/master/doc/XXL-JOB官方文档.md)
|
||||
- [Englis Documentation](https://github.com/xuxueli/xxl-job/blob/master/doc/XXL-JOB-Englis-Documentation.md)
|
||||
|
||||
### 特性
|
||||
|
||||
## Features
|
||||
- 1、简单:支持通过Web页面对任务进行CRUD操作,操作简单,一分钟上手;
|
||||
- 2、动态:支持动态修改任务状态、暂停/恢复任务,以及终止运行中任务,即时生效;
|
||||
- 3、调度中心HA(中心式):调度采用中心式设计,“调度中心”基于集群Quartz实现,可保证调度中心HA;
|
||||
|
@ -41,11 +68,8 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是
|
|||
- 23、分片广播任务:执行器集群部署时,任务路由策略选择"分片广播"情况下,一次任务调度将会广播触发对应集群中所有执行器执行一次任务,同时传递分片参数;可根据分片参数开发分片任务;
|
||||
- 24、动态分片:分片广播任务以执行器为维度进行分片,支持动态扩容执行器集群从而动态增加分片数量,协同进行业务处理;在进行大数据量业务操作时可显著提升任务处理能力和速度。
|
||||
|
||||
### 架构图
|
||||
|
||||
![输入图片说明](https://static.oschina.net/uploads/img/201707/17190028_aEE2.png "在这里输入图片标题")
|
||||
|
||||
### 发展
|
||||
## Development
|
||||
于2015年中,我在github上创建XXL-JOB项目仓库并提交第一个commit,随之进行系统结构设计,UI选型,交互设计……
|
||||
|
||||
于2015-11月,XXL-JOB终于RELEASE了第一个大版本V1.0, 随后我将之发布到OSCHINA,XXL-JOB在OSCHINA上获得了@红薯的热门推荐,同期分别达到了OSCHINA的“热门动弹”排行第一和git.oschina的开源软件月热度排行第一,在此特别感谢红薯,感谢大家的关注和支持。
|
||||
|
@ -56,7 +80,7 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是
|
|||
|
||||
于2017-05-13,在上海举办的 "[第62期开源中国源创会](https://www.oschina.net/event/2236961)" 的 "放码过来" 环节,我登台对XXL-JOB做了演讲,台下五百位在场观众反响热烈([图文回顾](https://www.oschina.net/question/2686220_2242120) )。
|
||||
|
||||
#### 我司大众点评目前已接入XXL-JOB,内部别名《Ferrari》(Ferrari基于XXL-JOB的V1.1版本定制而成,新接入应用推荐升级最新版本)。
|
||||
** 我司大众点评目前已接入XXL-JOB,内部别名《Ferrari》(Ferrari基于XXL-JOB的V1.1版本定制而成,新接入应用推荐升级最新版本)。**
|
||||
据最新统计, 自2016-01-21接入至2017-07-07期间,该系统已调度约60万余次,表现优异。新接入应用推荐使用最新版本,因为经过数个大版本的更新,系统的任务模型、UI交互模型以及底层调度通讯模型都有了较大的优化和提升,核心功能更加稳定高效。
|
||||
|
||||
至今,XXL-JOB已接入多家公司的线上产品线,接入场景如电商业务,O2O业务和大数据作业等,截止2016-07-19为止,XXL-JOB已接入的公司包括不限于:
|
||||
|
@ -94,60 +118,43 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是
|
|||
- 31、四川互宜达科技有限公司
|
||||
- 32、钱包行云(北京)科技有限公司
|
||||
- 33、重庆欣才集团
|
||||
- 34、咪咕互动娱乐有限公司(中国移动)
|
||||
- 35、北京诺亦腾科技有限公司
|
||||
- 36、增长引擎(北京)信息技术有限公司
|
||||
- ……
|
||||
|
||||
欢迎大家的关注和使用,XXL-JOB也将拥抱变化,持续发展。
|
||||
|
||||
|
||||
### 下载
|
||||
## Communication
|
||||
|
||||
#### 源码仓库地址 (将会在两个git仓库同步发布最新代码)
|
||||
|
||||
源码仓库地址 | Release Download
|
||||
--- | ---
|
||||
[https://github.com/xuxueli/xxl-job](https://github.com/xuxueli/xxl-job) | [Download](https://github.com/xuxueli/xxl-job/releases)
|
||||
[http://git.oschina.net/xuxueli0323/xxl-job](http://git.oschina.net/xuxueli0323/xxl-job) | [Download](http://git.oschina.net/xuxueli0323/xxl-job/releases)
|
||||
- 腾讯QQ群(6):399758605
|
||||
- 腾讯QQ群(5):138274130 (群即将满,请加群6)
|
||||
- 腾讯QQ群(4):464762661 (群即将满,请加群6)
|
||||
- 腾讯QQ群(3):242151780 (群即将满,请加群6)
|
||||
- 腾讯QQ群(2):438249535 (群即将满,请加群6)
|
||||
- 腾讯QQ群(1):367260654 (群即将满,请加群6)
|
||||
- [Gitter](https://gitter.im/xuxueli/xxl-job)
|
||||
|
||||
|
||||
#### 中央仓库地址 (最新Release版本:1.8.0)
|
||||
|
||||
```
|
||||
<!-- http://repo1.maven.org/maven2/com/xuxueli/xxl-job-core/ -->
|
||||
<dependency>
|
||||
<groupId>com.xuxueli</groupId>
|
||||
<artifactId>xxl-job-core</artifactId>
|
||||
<version>1.8.0</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
#### 博客地址 (将会在两个博客同步更新文档)
|
||||
|
||||
- [oschina地址](http://my.oschina.net/xuxueli/blog/690978)
|
||||
- [cnblogs地址](http://www.cnblogs.com/xuxueli/p/5021979.html)
|
||||
|
||||
#### 技术交流群 (仅作技术交流)
|
||||
## Issue
|
||||
如有问题可在 [Github Issues](https://github.com/xuxueli/xxl-job/issues/) 上提问,也可以加入上文技术交流群;
|
||||
|
||||
|
||||
- 群5:138274130 [![image](http://pub.idqqimg.com/wpa/images/group.png)](http://shang.qq.com/wpa/qunwpa?idkey=a3f3aea7e5943e7a24e9726495747ddc19bccd3592d7a70ecb5a97b616062241 )
|
||||
- 群4:464762661 (群即将满,请加群5)
|
||||
- 群3:242151780 (群即将满,请加群5)
|
||||
- 群2:438249535 (群即将满,请加群5)
|
||||
- 群1:367260654 (群即将满,请加群5)
|
||||
## User Registration
|
||||
登记仅为了产品推广,产品开源免费。
|
||||
请接入使用的公司或个人进行用户登记 [登记地址](https://github.com/xuxueli/xxl-job/issues/1 ) 。
|
||||
|
||||
|
||||
### 报告问题
|
||||
XXL-JOB托管在Github上,如有问题可在 [ISSUES](https://github.com/xuxueli/xxl-job/issues/) 上提问,也可以加入上文技术交流群;
|
||||
|
||||
### 接入登记(登记仅为了推广,产品开源免费)
|
||||
更多接入公司,欢迎在github [登记](https://github.com/xuxueli/xxl-job/issues/1 )
|
||||
|
||||
### 开源协议
|
||||
## Copyright and license
|
||||
产品开源免费,并且将持续提供免费的社区技术支持。个人或企业内部可自由的接入和使用。
|
||||
|
||||
XXL-JOB采用GPLv3协议,目的是为了保证用户的自由使用权利。协议可避免专利申请的特殊危险 "the GPL assures that patents cannot be used to render the program non-free.(摘自GPLv3)"。
|
||||
Copyright (c) 2015-present, xuxueli.
|
||||
|
||||
---
|
||||
### 支持的话可以扫一扫,支持 [XXL系列](https://github.com/xuxueli) 的建设:)
|
||||
## Donate
|
||||
支持的话可以扫一扫,请作者喝杯咖啡吧:)
|
||||
|
||||
微信:![输入图片说明](https://static.oschina.net/uploads/img/201707/07214300_qhxT.png "在这里输入图片标题")
|
||||
支付宝:![输入图片说明](http://images2015.cnblogs.com/blog/554415/201605/554415-20160513183306234-1939652116.png "在这里输入图片标题")
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
# 《A lightweight distributed task scheduling framework. "XXL-JOB"》
|
||||
|
||||
[![Build Status](https://travis-ci.org/xuxueli/xxl-job.svg?branch=master)](https://travis-ci.org/xuxueli/xxl-job)
|
||||
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.xuxueli/xxl-job/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.xuxueli/xxl-job/)
|
||||
[![GitHub release](https://img.shields.io/github/release/xuxueli/xxl-job.svg)](https://github.com/xuxueli/xxl-job/releases)
|
||||
[![License](https://img.shields.io/badge/license-GPLv3-blue.svg)](http://www.gnu.org/licenses/gpl-3.0.html)
|
||||
[![Gitter](https://badges.gitter.im/xuxueli/xxl-job.svg)](https://gitter.im/xuxueli/xxl-job?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
|
||||
## 1、Intro
|
||||
|
||||
### 1.1 overview
|
|
@ -86,13 +86,16 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是
|
|||
- 31、四川互宜达科技有限公司
|
||||
- 32、钱包行云(北京)科技有限公司
|
||||
- 33、重庆欣才集团
|
||||
- 34、咪咕互动娱乐有限公司(中国移动)
|
||||
- 35、北京诺亦腾科技有限公司
|
||||
- 36、增长引擎(北京)信息技术有限公司
|
||||
- ……
|
||||
|
||||
欢迎大家的关注和使用,XXL-JOB也将拥抱变化,持续发展。
|
||||
|
||||
### 1.4 下载
|
||||
|
||||
#### 源码仓库地址 (将会在两个git仓库同步发布最新代码)
|
||||
#### 源码仓库地址
|
||||
|
||||
源码仓库地址 | Release Download
|
||||
--- | ---
|
||||
|
@ -100,35 +103,36 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是
|
|||
[http://git.oschina.net/xuxueli0323/xxl-job](http://git.oschina.net/xuxueli0323/xxl-job) | [Download](http://git.oschina.net/xuxueli0323/xxl-job/releases)
|
||||
|
||||
|
||||
#### 中央仓库地址 (最新Release版本:1.8.0)
|
||||
#### 中央仓库地址
|
||||
|
||||
```
|
||||
<!-- http://repo1.maven.org/maven2/com/xuxueli/xxl-job-core/ -->
|
||||
<dependency>
|
||||
<groupId>com.xuxueli</groupId>
|
||||
<artifactId>xxl-job-core</artifactId>
|
||||
<version>1.8.0</version>
|
||||
<version>1.8.1</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
#### 博客地址 (将会在两个博客同步更新文档)
|
||||
#### 博客地址
|
||||
|
||||
- [oschina地址](http://my.oschina.net/xuxueli/blog/690978)
|
||||
- [cnblogs地址](http://www.cnblogs.com/xuxueli/p/5021979.html)
|
||||
|
||||
#### 技术交流群 (仅作技术交流)
|
||||
#### 技术交流
|
||||
|
||||
- 群5:138274130 [![image](http://pub.idqqimg.com/wpa/images/group.png)](http://shang.qq.com/wpa/qunwpa?idkey=a3f3aea7e5943e7a24e9726495747ddc19bccd3592d7a70ecb5a97b616062241 )
|
||||
- 群4:464762661 (群即将满,请加群5)
|
||||
- 群3:242151780 (群即将满,请加群5)
|
||||
- 群2:438249535 (群即将满,请加群5)
|
||||
- 群1:367260654 (群即将满,请加群5)
|
||||
- 腾讯QQ群(6):399758605
|
||||
- 腾讯QQ群(5):138274130 (群即将满,请加群6)
|
||||
- 腾讯QQ群(4):464762661 (群即将满,请加群6)
|
||||
- 腾讯QQ群(3):242151780 (群即将满,请加群6)
|
||||
- 腾讯QQ群(2):438249535 (群即将满,请加群6)
|
||||
- 腾讯QQ群(1):367260654 (群即将满,请加群6)
|
||||
|
||||
### 1.5 环境
|
||||
- JDK:1.7+
|
||||
- Servlet/JSP Spec:3.1/2.3
|
||||
- Tomcat:8.5.x/Jetty9.2
|
||||
- Spring-boot:1.3.8/Spring4.x
|
||||
- Tomcat:8.5.x/Jetty9.2.x
|
||||
- Spring-boot:1.5.x/Spring4.x
|
||||
- Mysql:5.6+
|
||||
- Maven:3+
|
||||
|
||||
|
@ -136,18 +140,18 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是
|
|||
## 二、快速入门
|
||||
|
||||
### 2.1 初始化“调度数据库”
|
||||
请下载项目源码并解压,获取 "调度数据库初始化SQL脚本" 并执行即可。正常情况下应该生成16张表,脚本文件位置为:
|
||||
请下载项目源码并解压,获取 "调度数据库初始化SQL脚本" 并执行即可,正常情况下应该生成16张表。
|
||||
|
||||
源码解压根目录\xxl-job\db\tables_xxl_job.sql
|
||||
"调度数据库初始化SQL脚本" 位置为:
|
||||
|
||||
/xxl-job/db/tables_xxl_job.sql
|
||||
|
||||
调度中心支持集群部署,集群情况下各节点务必连接同一个mysql实例;
|
||||
|
||||
如果mysql做主从,调度中心集群节点务必强制走主库;
|
||||
|
||||
### 2.2 编译源码
|
||||
解压源码,按照maven格式将源码导入IDE, 使用maven进行编译即可,源码结构如下图所示:
|
||||
|
||||
![输入图片说明](https://static.oschina.net/uploads/img/201705/11214348_aGgr.png "在这里输入图片标题")
|
||||
解压源码,按照maven格式将源码导入IDE, 使用maven进行编译即可,源码结构如下:
|
||||
|
||||
xxl-job-admin:调度中心
|
||||
xxl-job-core:公共依赖
|
||||
|
@ -160,14 +164,16 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是
|
|||
作用:统一管理任务调度平台上调度任务,负责触发调度执行。
|
||||
|
||||
#### 步骤一:调度中心配置:
|
||||
配置文件以及配置属性如下图所示。
|
||||
调度中心配置文件地址:
|
||||
|
||||
![输入图片说明](https://static.oschina.net/uploads/img/201705/11214752_Ifvp.png "在这里输入图片标题")
|
||||
/xxl-job/xxl-job-admin/src/main/resources/xxl-job-admin.properties
|
||||
|
||||
|
||||
调度中心配置内容说明:
|
||||
|
||||
### 调度中心JDBC链接:链接地址请保持和 2.1章节 所创建的调度数据库的地址一致
|
||||
xxl.job.db.driverClass=com.mysql.jdbc.Driver
|
||||
xxl.job.db.url=jdbc:mysql://localhost:3306/xxl-job?useUnicode=true&characterEncoding=UTF-8
|
||||
xxl.job.db.url=jdbc:mysql://localhost:3306/xxl-job?useUnicode=true&characterEncoding=UTF-8
|
||||
xxl.job.db.user=root
|
||||
xxl.job.db.password=root_pwd
|
||||
|
||||
|
@ -179,9 +185,12 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是
|
|||
xxl.job.mail.sendFrom=ovono802302@163.com
|
||||
xxl.job.mail.sendNick=《任务调度平台XXL-JOB》
|
||||
|
||||
# 登录账号
|
||||
### 登录账号
|
||||
xxl.job.login.username=admin
|
||||
xxl.job.login.password=123456
|
||||
|
||||
### 调度中心通讯TOKEN,非空时启用
|
||||
xxl.job.accessToken=
|
||||
|
||||
#### 步骤二:部署项目:
|
||||
如果已经正确进行上述配置,可将项目编译打war包并部署到tomcat中。
|
||||
|
@ -191,6 +200,13 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是
|
|||
|
||||
至此“调度中心”项目已经部署成功。
|
||||
|
||||
#### 步骤三:调度中心集群(可选):
|
||||
调度中心支持集群部署,提升调度系统可用性。
|
||||
|
||||
集群部署唯一要求为:保证每个集群节点配置(db和登陆账号等)保持一致。调度中心通过db配置区分不同集群。
|
||||
|
||||
调度中心在集群部署时可通过nginx负载均衡,此时可以为集群分配一个域名。该域名一方面可以用于访问,另一方面也可以用于配置执行器回调地址。
|
||||
|
||||
### 2.4 配置部署“执行器项目”
|
||||
|
||||
“执行器”项目:xxl-job-executor-example (如新建执行器项目,可参考该Example执行器项目的配置步骤;)
|
||||
|
@ -200,10 +216,11 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是
|
|||
确认pom文件中引入了 "xxl-job-core" 的maven依赖;
|
||||
|
||||
#### 步骤二:执行器配置
|
||||
配置文件以及配置属性如下图所示。
|
||||
执行器配置配置文件地址:
|
||||
|
||||
![输入图片说明](https://static.oschina.net/uploads/img/201705/11214800_7G3o.png "在这里输入图片标题")
|
||||
/xxl-job/xxl-job-executor-example/src/main/resources/xxl-job-executor.properties
|
||||
|
||||
执行器配置配置内容说明:
|
||||
|
||||
### xxl-job admin address list:调度中心部署跟地址:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调"。
|
||||
xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin
|
||||
|
@ -215,6 +232,9 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是
|
|||
|
||||
### xxl-job log path:执行器运行日志文件存储的磁盘位置
|
||||
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler/
|
||||
|
||||
### xxl-job, access token:执行器通讯TOKEN,非空时启用
|
||||
xxl.job.accessToken=
|
||||
|
||||
|
||||
#### 步骤三:执行器组件配置
|
||||
|
@ -225,7 +245,7 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是
|
|||
1、JobHandler 扫描路径:自动扫描容器中JobHandler;
|
||||
2、执行器Excutor配置:执行器核心配置;
|
||||
|
||||
#### 步骤四:部署项目:
|
||||
#### 步骤四:部署执行器项目:
|
||||
如果已经正确进行上述配置,可将执行器项目编译打部署,系统提供两个执行器example项目,选择其中一个即可,各自的部署方式如下。
|
||||
|
||||
xxl-job-executor-example:项目编译打包成WAR包,并部署到tomcat中。
|
||||
|
@ -233,6 +253,11 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是
|
|||
|
||||
至此“执行器”项目已经部署结束。
|
||||
|
||||
#### 步骤五:执行器集群(可选):
|
||||
执行器支持集群部署,提升调度系统可用性,同时提升任务处理能力。
|
||||
|
||||
集群部署唯一要求为:保证集群中每个执行器的配置项 "xxl.job.admin.addresses/调度中心地址" 保持一致,执行器根据该配置进行执行器自动注册等操作。
|
||||
|
||||
|
||||
### 2.5 开发第一个任务“Hello World”
|
||||
本示例以新建一个 “GLUE模式(Java)” 运行模式的任务为例。更多有关任务的详细配置,请查看“章节三:任务详解”。
|
||||
|
@ -706,6 +731,16 @@ XXL-JOB会为每次调度请求生成一个单独的日志文件,需要通过
|
|||
- 1、分片任务场景:10个执行器的集群来处理10w条数据,每台机器只需要处理1w条数据,耗时降低10倍;
|
||||
- 2、广播任务场景:广播执行器机器运行shell脚本、广播集群节点进行缓存更新等
|
||||
|
||||
#### 5、10 访问令牌(AccessToken)
|
||||
为提升系统安全性,调度中心和执行器进行安全性校验,双方AccessToken匹配才允许通讯;
|
||||
|
||||
调度中心和执行器,可通过配置项 "xxl.job.accessToken" 进行AccessToken的设置。
|
||||
|
||||
调度中心和执行器,如果需要正常通讯,只有两种设置;
|
||||
|
||||
- 设置一:调度中心和执行器,均不设置AccessToken;关闭安全性校验;
|
||||
- 设置二:调度中心和执行器,设置了相同的AccessToken;
|
||||
|
||||
|
||||
## 六、版本更新日志
|
||||
#### 6.1 版本 V1.1.x,新特性[2015-12-05]
|
||||
|
@ -896,41 +931,49 @@ Tips: 历史版本(V1.3.x)目前已经Release至稳定版本, 进入维护阶段
|
|||
- 10、执行日志,支持根据运行 "状态" 筛选日志;
|
||||
- 11、调度中心任务注册检测逻辑优化;
|
||||
|
||||
#### 6.18 版本 V1.8.1 特性[快照版本]
|
||||
#### 6.18 版本 V1.8.1 特性[2017-07-30]
|
||||
- 1、分片广播任务:执行器集群部署时,任务路由策略选择"分片广播"情况下,一次任务调度将会广播触发集群中所有执行器执行一次任务,可根据分片参数处理分片任务;
|
||||
- 2、动态分片:分片广播任务以执行器为维度进行分片,支持动态扩容执行器集群从而动态增加分片数量,协同进行业务处理;在进行大数据量业务操作时可显著提升任务处理能力和速度。
|
||||
- 3、执行器JobHandler禁止命名冲突;
|
||||
- 4、执行器集群地址列表进行自然排序;
|
||||
- 5、调度中心,DAO层代码精简优化并且新增测试用例覆盖;
|
||||
- 6、调度中心API服务改为自研RPC形式,统一底层通讯模型;
|
||||
- 7、新增调度中心API服务测试Demo,方便在调度中心API扩展和测试;
|
||||
- 8、任务列表页交互优化,更换执行器分组时自动刷新任务列表,新建任务时默认定位在当前执行器位置;
|
||||
- 9、访问令牌(accessToken):为提升系统安全性,调度中心和执行器进行安全性校验,双方AccessToken匹配才允许通讯;
|
||||
- 10、springboot版本执行器,升级至1.5.6.RELEASE版本;
|
||||
- 11、统一maven依赖版本管理;
|
||||
|
||||
#### TODO LIST
|
||||
- 1、任务权限管理:执行器为粒度分配权限,核心操作校验权限;
|
||||
- 2、任务分片路由:分片采用一致性Hash算法计算出尽量稳定的分片顺序,即使注册机器存在波动也不会引起分批分片顺序大的波动;
|
||||
- 3、失败重试优化:目前失败重试逻辑为,在本次调度请求失败后重新执行一次请求逻辑。优化点为针对调度和执行失败时均做失败重试,重试时重新触发一次完整调度,这将可能导致失败是调度死循环,考虑中。
|
||||
- 2、任务分片路由:分片采用一致性Hash算法计算出尽量稳定的分片顺序,即使注册机器存在波动也不会引起分批分片顺序大的波动;目前采用IP自然排序,可以满足需求,待定;
|
||||
- 3、失败重试优化:目前失败重试逻辑为,在本次调度请求失败后重新执行一次请求逻辑。优化点为针对调度和执行失败时均做失败重试,重试时重新触发一次完整调度,这将可能导致失败是调度死循环,待定。
|
||||
- 4、回调失败写文件,查看日志时读文件确认,重启后回调确认;
|
||||
- 5、任务依赖,流程图,子任务+会签任务,各节点日志;
|
||||
- 6、调度任务优先级;
|
||||
- 7、移除quartz依赖,重写调度模块:新增或恢复任务时将下次执行记录插入delayqueue,调度中心集群竞争分布式锁,成功节点批量加载到期delayqueue数据,批量执行。
|
||||
- 8、任务执行结果回调失败后重试:待定,防止回调死循环;
|
||||
- 9、springboot 和 docker镜像,并且推送docker镜像到中央仓库,更进一步实现产品开箱即用;
|
||||
- 10、安全校验:调度中心和执行器约定公共密匙,只有密匙一致才允许相互通讯;
|
||||
- 8、springboot 和 docker镜像,并且推送docker镜像到中央仓库,更进一步实现产品开箱即用;
|
||||
- 9、国际化:调度中心界面 + 官方文档,新增英文版本。
|
||||
- 10、执行器摘除:执行器销毁时,主动通知调度中心并摘除对应执行器节点,提高执行器状态感知的时效性。
|
||||
|
||||
## 七、其他
|
||||
|
||||
#### 7.1 报告问题
|
||||
XXL-JOB托管在Github上,如有问题可在 [ISSUES](https://github.com/xuxueli/xxl-job/issues/) 上提问,也可以加入上文技术交流群;
|
||||
|
||||
#### 7.2 接入登记(登记仅为了推广,产品开源免费)
|
||||
更多接入公司,欢迎在github [登记](https://github.com/xuxueli/xxl-job/issues/1 )
|
||||
#### 7.2 用户接入登记
|
||||
登记仅为了产品推广,产品开源免费。
|
||||
请接入使用的公司或个人进行用户登记 [登记地址](https://github.com/xuxueli/xxl-job/issues/1 ) 。
|
||||
|
||||
#### 7.3 开源协议
|
||||
#### 7.3 开源协议和版权
|
||||
产品开源免费,并且将持续提供免费的社区技术支持。个人或企业内部可自由的接入和使用。
|
||||
|
||||
XXL-JOB采用GPLv3协议,目的是为了保证用户的自由使用权利。协议可避免专利申请的特殊危险 "the GPL assures that patents cannot be used to render the program non-free.(摘自GPLv3)"。
|
||||
Copyright (c) 2015-present, xuxueli.
|
||||
|
||||
---
|
||||
#### 支持的话可以扫一扫,支持 [XXL系列](https://github.com/xuxueli) 的建设:)
|
||||
#### 捐赠
|
||||
支持的话可以扫一扫,请作者喝杯咖啡吧:)
|
||||
|
||||
微信:![输入图片说明](https://static.oschina.net/uploads/img/201707/07214300_qhxT.png "在这里输入图片标题")
|
||||
支付宝:![输入图片说明](http://images2015.cnblogs.com/blog/554415/201605/554415-20160513183306234-1939652116.png "在这里输入图片标题")
|
||||
|
|
33
pom.xml
33
pom.xml
|
@ -3,7 +3,7 @@
|
|||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.xuxueli</groupId>
|
||||
<artifactId>xxl-job</artifactId>
|
||||
<version>1.8.1-SNAPSHOT</version>
|
||||
<version>1.8.2-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
|
@ -17,6 +17,37 @@
|
|||
<module>xxl-job-executor-springboot-example</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
<javax.servlet-api.version>3.0.1</javax.servlet-api.version>
|
||||
<jsp-api.version>2.2</jsp-api.version>
|
||||
|
||||
<spring.version>3.2.18.RELEASE</spring.version>
|
||||
<jackson-mapper-asl.version>1.9.13</jackson-mapper-asl.version>
|
||||
<aspectjweaver.version>1.8.7</aspectjweaver.version>
|
||||
<slf4j-api.version>1.7.25</slf4j-api.version>
|
||||
<freemarker.version>2.3.20</freemarker.version>
|
||||
<junit.version>4.11</junit.version>
|
||||
|
||||
<jetty-server.version>9.2.22.v20170606</jetty-server.version>
|
||||
<hessian.version>4.0.38</hessian.version>
|
||||
<httpclient.version>4.3.6</httpclient.version>
|
||||
|
||||
<commons-exec.version>1.3</commons-exec.version>
|
||||
<commons-beanutils.version>1.9.2</commons-beanutils.version>
|
||||
<commons-lang.version>2.6</commons-lang.version>
|
||||
|
||||
<c3p0.version>0.9.5.2</c3p0.version>
|
||||
<mysql-connector-java.version>5.1.29</mysql-connector-java.version>
|
||||
<mybatis-spring.version>1.2.2</mybatis-spring.version>
|
||||
<mybatis.version>3.2.8</mybatis.version>
|
||||
|
||||
<groovy-all.version>2.4.5</groovy-all.version>
|
||||
<mail.version>1.4.6</mail.version>
|
||||
<quartz.version>2.3.0</quartz.version>
|
||||
|
||||
<spring-boot.version>1.5.6.RELEASE</spring-boot.version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
|
|
@ -4,15 +4,11 @@
|
|||
<parent>
|
||||
<groupId>com.xuxueli</groupId>
|
||||
<artifactId>xxl-job</artifactId>
|
||||
<version>1.8.1-SNAPSHOT</version>
|
||||
<version>1.8.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>xxl-job-admin</artifactId>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<properties>
|
||||
<spring.version>3.2.17.RELEASE</spring.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- springframe start -->
|
||||
<dependency>
|
||||
|
@ -40,59 +36,59 @@
|
|||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
<version>1.8.7</version>
|
||||
<version>${aspectjweaver.version}</version>
|
||||
</dependency>
|
||||
<!-- jackson (support spring json) -->
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-mapper-asl</artifactId>
|
||||
<version>1.9.13</version>
|
||||
<version>${jackson-mapper-asl.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- slf4j -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<version>1.7.21</version>
|
||||
<version>${slf4j-api.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- freemarker -->
|
||||
<dependency>
|
||||
<groupId>org.freemarker</groupId>
|
||||
<artifactId>freemarker</artifactId>
|
||||
<version>2.3.20</version>
|
||||
<version>${freemarker.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- commons-beanutils -->
|
||||
<dependency>
|
||||
<groupId>commons-beanutils</groupId>
|
||||
<artifactId>commons-beanutils</artifactId>
|
||||
<version>1.9.2</version>
|
||||
<version>${commons-beanutils.version}</version>
|
||||
</dependency>
|
||||
<!-- commons-lang -->
|
||||
<dependency>
|
||||
<groupId>commons-lang</groupId>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
<version>2.6</version>
|
||||
<version>${commons-lang.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- servlet -->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>3.0.1</version>
|
||||
<version>${javax.servlet-api.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet.jsp</groupId>
|
||||
<artifactId>jsp-api</artifactId>
|
||||
<version>2.2</version>
|
||||
<version>${jsp-api.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- junit -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.11</version>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
@ -100,45 +96,46 @@
|
|||
<dependency>
|
||||
<groupId>com.mchange</groupId>
|
||||
<artifactId>c3p0</artifactId>
|
||||
<version>0.9.5.2</version>
|
||||
</dependency>
|
||||
<!-- mybatis-spring -->
|
||||
<dependency>
|
||||
<groupId>org.mybatis</groupId>
|
||||
<artifactId>mybatis-spring</artifactId>
|
||||
<version>1.2.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mybatis</groupId>
|
||||
<artifactId>mybatis</artifactId>
|
||||
<version>3.2.8</version>
|
||||
<version>${c3p0.version}</version>
|
||||
</dependency>
|
||||
<!-- mysql-connector -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.29</version>
|
||||
<version>${mysql-connector-java.version}</version>
|
||||
</dependency>
|
||||
<!-- mybatis-spring -->
|
||||
<dependency>
|
||||
<groupId>org.mybatis</groupId>
|
||||
<artifactId>mybatis-spring</artifactId>
|
||||
<version>${mybatis-spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mybatis</groupId>
|
||||
<artifactId>mybatis</artifactId>
|
||||
<version>${mybatis.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- httpclient -->
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.3.6</version>
|
||||
<version>${httpclient.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- javax.mail -->
|
||||
<dependency>
|
||||
<groupId>javax.mail</groupId>
|
||||
<artifactId>mail</artifactId>
|
||||
<version>1.4.6</version>
|
||||
<version>${mail.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- quartz :quartz-2.2.3/c3p0-0.9.1.1/slf4j-api-1.6.6 -->
|
||||
<dependency>
|
||||
<groupId>org.quartz-scheduler</groupId>
|
||||
<artifactId>quartz</artifactId>
|
||||
<version>2.3.0</version>
|
||||
<version>${quartz.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- xxl-job-core -->
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.xxl.job.admin.controller;
|
||||
|
||||
import com.xxl.job.admin.controller.annotation.PermessionLimit;
|
||||
import com.xxl.job.core.biz.AdminBiz;
|
||||
import com.xxl.job.core.rpc.codec.RpcRequest;
|
||||
import com.xxl.job.core.rpc.codec.RpcResponse;
|
||||
import com.xxl.job.core.rpc.netcom.NetComServerFactory;
|
||||
|
@ -46,7 +47,7 @@ public class JobApiController {
|
|||
}
|
||||
}
|
||||
|
||||
@RequestMapping("/api")
|
||||
@RequestMapping(AdminBiz.MAPPING)
|
||||
@PermessionLimit(limit=false)
|
||||
public void api(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ public class JobInfoController {
|
|||
private XxlJobService xxlJobService;
|
||||
|
||||
@RequestMapping
|
||||
public String index(Model model) {
|
||||
public String index(Model model, @RequestParam(required = false, defaultValue = "-1") int jobGroup) {
|
||||
|
||||
// 枚举-字典
|
||||
model.addAttribute("ExecutorRouteStrategyEnum", ExecutorRouteStrategyEnum.values()); // 路由策略-列表
|
||||
|
@ -44,6 +44,8 @@ public class JobInfoController {
|
|||
// 任务组
|
||||
List<XxlJobGroup> jobGroupList = xxlJobGroupDao.findAll();
|
||||
model.addAttribute("JobGroupList", jobGroupList);
|
||||
model.addAttribute("jobGroup", jobGroup);
|
||||
|
||||
return "jobinfo/jobinfo.index";
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.xxl.job.admin.controller;
|
|||
import com.xxl.job.admin.core.model.XxlJobGroup;
|
||||
import com.xxl.job.admin.core.model.XxlJobInfo;
|
||||
import com.xxl.job.admin.core.model.XxlJobLog;
|
||||
import com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler;
|
||||
import com.xxl.job.admin.dao.XxlJobGroupDao;
|
||||
import com.xxl.job.admin.dao.XxlJobInfoDao;
|
||||
import com.xxl.job.admin.dao.XxlJobLogDao;
|
||||
|
@ -12,6 +13,8 @@ import com.xxl.job.core.biz.model.ReturnT;
|
|||
import com.xxl.job.core.rpc.netcom.NetComClientProxy;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.time.DateUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
@ -32,6 +35,7 @@ import java.util.Map;
|
|||
@Controller
|
||||
@RequestMapping("/joblog")
|
||||
public class JobLogController {
|
||||
private static Logger logger = LoggerFactory.getLogger(JobLogController.class);
|
||||
|
||||
@Resource
|
||||
private XxlJobGroupDao xxlJobGroupDao;
|
||||
|
@ -116,7 +120,7 @@ public class JobLogController {
|
|||
@ResponseBody
|
||||
public ReturnT<LogResult> logDetailCat(String executorAddress, long triggerTime, int logId, int fromLineNum){
|
||||
try {
|
||||
ExecutorBiz executorBiz = (ExecutorBiz) new NetComClientProxy(ExecutorBiz.class, executorAddress).getObject();
|
||||
ExecutorBiz executorBiz = XxlJobDynamicScheduler.getExecutorBiz(executorAddress);
|
||||
ReturnT<LogResult> logResult = executorBiz.log(triggerTime, logId, fromLineNum);
|
||||
|
||||
// is end
|
||||
|
@ -129,7 +133,7 @@ public class JobLogController {
|
|||
|
||||
return logResult;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
logger.error(e.getMessage(), e);
|
||||
return new ReturnT<LogResult>(ReturnT.FAIL_CODE, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
@ -148,14 +152,14 @@ public class JobLogController {
|
|||
}
|
||||
|
||||
// request of kill
|
||||
ExecutorBiz executorBiz = null;
|
||||
ReturnT<String> runResult = null;
|
||||
try {
|
||||
executorBiz = (ExecutorBiz) new NetComClientProxy(ExecutorBiz.class, log.getExecutorAddress()).getObject();
|
||||
ExecutorBiz executorBiz = XxlJobDynamicScheduler.getExecutorBiz(log.getExecutorAddress());
|
||||
runResult = executorBiz.kill(jobInfo.getId());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return new ReturnT<String>(500, e.getMessage());
|
||||
logger.error(e.getMessage(), e);
|
||||
runResult = new ReturnT<String>(500, e.getMessage());
|
||||
}
|
||||
ReturnT<String> runResult = executorBiz.kill(jobInfo.getId());
|
||||
|
||||
if (ReturnT.SUCCESS_CODE == runResult.getCode()) {
|
||||
log.setHandleCode(ReturnT.FAIL_CODE);
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
package com.xxl.job.admin.core.route;
|
||||
|
||||
import com.xxl.job.core.biz.ExecutorBiz;
|
||||
import com.xxl.job.core.biz.model.ReturnT;
|
||||
import com.xxl.job.core.biz.model.TriggerParam;
|
||||
import com.xxl.job.core.rpc.netcom.NetComClientProxy;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -24,30 +22,4 @@ public abstract class ExecutorRouter {
|
|||
*/
|
||||
public abstract ReturnT<String> routeRun(TriggerParam triggerParam, ArrayList<String> addressList);
|
||||
|
||||
/**
|
||||
* run executor
|
||||
* @param triggerParam
|
||||
* @param address
|
||||
* @return ReturnT.content: final address
|
||||
*/
|
||||
public static ReturnT<String> runExecutor(TriggerParam triggerParam, String address){
|
||||
ReturnT<String> runResult = null;
|
||||
try {
|
||||
ExecutorBiz executorBiz = (ExecutorBiz) new NetComClientProxy(ExecutorBiz.class, address).getObject();
|
||||
runResult = executorBiz.run(triggerParam);
|
||||
} catch (Exception e) {
|
||||
logger.error("", e);
|
||||
runResult = new ReturnT<String>(ReturnT.FAIL_CODE, ""+e );
|
||||
}
|
||||
|
||||
StringBuffer runResultSB = new StringBuffer("触发调度:");
|
||||
runResultSB.append("<br>address:").append(address);
|
||||
runResultSB.append("<br>code:").append(runResult.getCode());
|
||||
runResultSB.append("<br>msg:").append(runResult.getMsg());
|
||||
|
||||
runResult.setMsg(runResultSB.toString());
|
||||
runResult.setContent(address);
|
||||
return runResult;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
package com.xxl.job.admin.core.route.strategy;
|
||||
|
||||
import com.xxl.job.admin.core.route.ExecutorRouter;
|
||||
import com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler;
|
||||
import com.xxl.job.admin.core.trigger.XxlJobTrigger;
|
||||
import com.xxl.job.core.biz.ExecutorBiz;
|
||||
import com.xxl.job.core.biz.model.ReturnT;
|
||||
import com.xxl.job.core.biz.model.TriggerParam;
|
||||
import com.xxl.job.core.rpc.netcom.NetComClientProxy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
@ -25,7 +26,7 @@ public class ExecutorRouteBusyover extends ExecutorRouter {
|
|||
// beat
|
||||
ReturnT<String> idleBeatResult = null;
|
||||
try {
|
||||
ExecutorBiz executorBiz = (ExecutorBiz) new NetComClientProxy(ExecutorBiz.class, address).getObject();
|
||||
ExecutorBiz executorBiz = XxlJobDynamicScheduler.getExecutorBiz(address);
|
||||
idleBeatResult = executorBiz.idleBeat(triggerParam.getJobId());
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
|
@ -40,7 +41,7 @@ public class ExecutorRouteBusyover extends ExecutorRouter {
|
|||
// beat success
|
||||
if (idleBeatResult.getCode() == ReturnT.SUCCESS_CODE) {
|
||||
|
||||
ReturnT<String> runResult = runExecutor(triggerParam, address);
|
||||
ReturnT<String> runResult = XxlJobTrigger.runExecutor(triggerParam, address);
|
||||
idleBeatResultSB.append("<br><br>").append(runResult.getMsg());
|
||||
|
||||
// result
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.xxl.job.admin.core.route.strategy;
|
||||
|
||||
import com.xxl.job.admin.core.route.ExecutorRouter;
|
||||
import com.xxl.job.admin.core.trigger.XxlJobTrigger;
|
||||
import com.xxl.job.core.biz.model.ReturnT;
|
||||
import com.xxl.job.core.biz.model.TriggerParam;
|
||||
|
||||
|
@ -82,7 +83,7 @@ public class ExecutorRouteConsistentHash extends ExecutorRouter {
|
|||
String address = route(triggerParam.getJobId(), addressList);
|
||||
|
||||
// run executor
|
||||
ReturnT<String> runResult = runExecutor(triggerParam, address);
|
||||
ReturnT<String> runResult = XxlJobTrigger.runExecutor(triggerParam, address);
|
||||
runResult.setContent(address);
|
||||
return runResult;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
package com.xxl.job.admin.core.route.strategy;
|
||||
|
||||
import com.xxl.job.admin.core.route.ExecutorRouter;
|
||||
import com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler;
|
||||
import com.xxl.job.admin.core.trigger.XxlJobTrigger;
|
||||
import com.xxl.job.core.biz.ExecutorBiz;
|
||||
import com.xxl.job.core.biz.model.ReturnT;
|
||||
import com.xxl.job.core.biz.model.TriggerParam;
|
||||
import com.xxl.job.core.rpc.netcom.NetComClientProxy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
@ -25,7 +26,7 @@ public class ExecutorRouteFailover extends ExecutorRouter {
|
|||
// beat
|
||||
ReturnT<String> beatResult = null;
|
||||
try {
|
||||
ExecutorBiz executorBiz = (ExecutorBiz) new NetComClientProxy(ExecutorBiz.class, address).getObject();
|
||||
ExecutorBiz executorBiz = XxlJobDynamicScheduler.getExecutorBiz(address);
|
||||
beatResult = executorBiz.beat();
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
|
@ -40,7 +41,7 @@ public class ExecutorRouteFailover extends ExecutorRouter {
|
|||
// beat success
|
||||
if (beatResult.getCode() == ReturnT.SUCCESS_CODE) {
|
||||
|
||||
ReturnT<String> runResult = runExecutor(triggerParam, address);
|
||||
ReturnT<String> runResult = XxlJobTrigger.runExecutor(triggerParam, address);
|
||||
beatResultSB.append("<br><br>").append(runResult.getMsg());
|
||||
|
||||
// result
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.xxl.job.admin.core.route.strategy;
|
||||
|
||||
import com.xxl.job.admin.core.model.XxlJobLog;
|
||||
import com.xxl.job.admin.core.route.ExecutorRouter;
|
||||
import com.xxl.job.admin.core.trigger.XxlJobTrigger;
|
||||
import com.xxl.job.core.biz.model.ReturnT;
|
||||
import com.xxl.job.core.biz.model.TriggerParam;
|
||||
|
||||
|
@ -23,7 +23,7 @@ public class ExecutorRouteFirst extends ExecutorRouter {
|
|||
String address = route(triggerParam.getJobId(), addressList);
|
||||
|
||||
// run executor
|
||||
ReturnT<String> runResult = runExecutor(triggerParam, address);
|
||||
ReturnT<String> runResult = XxlJobTrigger.runExecutor(triggerParam, address);
|
||||
runResult.setContent(address);
|
||||
return runResult;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.xxl.job.admin.core.route.strategy;
|
||||
|
||||
import com.xxl.job.admin.core.route.ExecutorRouter;
|
||||
import com.xxl.job.admin.core.trigger.XxlJobTrigger;
|
||||
import com.xxl.job.core.biz.model.ReturnT;
|
||||
import com.xxl.job.core.biz.model.TriggerParam;
|
||||
|
||||
|
@ -62,7 +63,7 @@ public class ExecutorRouteLFU extends ExecutorRouter {
|
|||
String address = route(triggerParam.getJobId(), addressList);
|
||||
|
||||
// run executor
|
||||
ReturnT<String> runResult = runExecutor(triggerParam, address);
|
||||
ReturnT<String> runResult = XxlJobTrigger.runExecutor(triggerParam, address);
|
||||
runResult.setContent(address);
|
||||
return runResult;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.xxl.job.admin.core.route.strategy;
|
||||
|
||||
import com.xxl.job.admin.core.route.ExecutorRouter;
|
||||
import com.xxl.job.admin.core.trigger.XxlJobTrigger;
|
||||
import com.xxl.job.core.biz.model.ReturnT;
|
||||
import com.xxl.job.core.biz.model.TriggerParam;
|
||||
|
||||
|
@ -61,7 +62,7 @@ public class ExecutorRouteLRU extends ExecutorRouter {
|
|||
String address = route(triggerParam.getJobId(), addressList);
|
||||
|
||||
// run executor
|
||||
ReturnT<String> runResult = runExecutor(triggerParam, address);
|
||||
ReturnT<String> runResult = XxlJobTrigger.runExecutor(triggerParam, address);
|
||||
runResult.setContent(address);
|
||||
return runResult;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.xxl.job.admin.core.route.strategy;
|
||||
|
||||
import com.xxl.job.admin.core.model.XxlJobLog;
|
||||
import com.xxl.job.admin.core.route.ExecutorRouter;
|
||||
import com.xxl.job.admin.core.trigger.XxlJobTrigger;
|
||||
import com.xxl.job.core.biz.model.ReturnT;
|
||||
import com.xxl.job.core.biz.model.TriggerParam;
|
||||
|
||||
|
@ -22,7 +22,7 @@ public class ExecutorRouteLast extends ExecutorRouter {
|
|||
String address = route(triggerParam.getJobId(), addressList);
|
||||
|
||||
// run executor
|
||||
ReturnT<String> runResult = runExecutor(triggerParam, address);
|
||||
ReturnT<String> runResult = XxlJobTrigger.runExecutor(triggerParam, address);
|
||||
runResult.setContent(address);
|
||||
return runResult;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.xxl.job.admin.core.route.strategy;
|
||||
|
||||
import com.xxl.job.admin.core.route.ExecutorRouter;
|
||||
import com.xxl.job.admin.core.trigger.XxlJobTrigger;
|
||||
import com.xxl.job.core.biz.model.ReturnT;
|
||||
import com.xxl.job.core.biz.model.TriggerParam;
|
||||
|
||||
|
@ -25,7 +26,7 @@ public class ExecutorRouteRandom extends ExecutorRouter {
|
|||
String address = route(triggerParam.getJobId(), addressList);
|
||||
|
||||
// run executor
|
||||
ReturnT<String> runResult = runExecutor(triggerParam, address);
|
||||
ReturnT<String> runResult = XxlJobTrigger.runExecutor(triggerParam, address);
|
||||
runResult.setContent(address);
|
||||
return runResult;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.xxl.job.admin.core.route.strategy;
|
||||
|
||||
import com.xxl.job.admin.core.route.ExecutorRouter;
|
||||
import com.xxl.job.admin.core.trigger.XxlJobTrigger;
|
||||
import com.xxl.job.core.biz.model.ReturnT;
|
||||
import com.xxl.job.core.biz.model.TriggerParam;
|
||||
|
||||
|
@ -41,7 +42,7 @@ public class ExecutorRouteRound extends ExecutorRouter {
|
|||
String address = route(triggerParam.getJobId(), addressList);
|
||||
|
||||
// run executor
|
||||
ReturnT<String> runResult = runExecutor(triggerParam, address);
|
||||
ReturnT<String> runResult = XxlJobTrigger.runExecutor(triggerParam, address);
|
||||
runResult.setContent(address);
|
||||
return runResult;
|
||||
}
|
||||
|
|
|
@ -9,62 +9,52 @@ import com.xxl.job.admin.dao.XxlJobInfoDao;
|
|||
import com.xxl.job.admin.dao.XxlJobLogDao;
|
||||
import com.xxl.job.admin.dao.XxlJobRegistryDao;
|
||||
import com.xxl.job.core.biz.AdminBiz;
|
||||
import com.xxl.job.core.biz.ExecutorBiz;
|
||||
import com.xxl.job.core.rpc.netcom.NetComClientProxy;
|
||||
import com.xxl.job.core.rpc.netcom.NetComServerFactory;
|
||||
import org.quartz.*;
|
||||
import org.quartz.Trigger.TriggerState;
|
||||
import org.quartz.impl.matchers.GroupMatcher;
|
||||
import org.quartz.impl.triggers.CronTriggerImpl;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* base quartz scheduler util
|
||||
* @author xuxueli 2015-12-19 16:13:53
|
||||
*/
|
||||
public final class XxlJobDynamicScheduler implements ApplicationContextAware, InitializingBean {
|
||||
public final class XxlJobDynamicScheduler implements ApplicationContextAware {
|
||||
private static final Logger logger = LoggerFactory.getLogger(XxlJobDynamicScheduler.class);
|
||||
|
||||
// Scheduler
|
||||
|
||||
// ---------------------- param ----------------------
|
||||
|
||||
// scheduler
|
||||
private static Scheduler scheduler;
|
||||
public void setScheduler(Scheduler scheduler) {
|
||||
XxlJobDynamicScheduler.scheduler = scheduler;
|
||||
}
|
||||
|
||||
// init
|
||||
public void init() throws Exception {
|
||||
// admin registry monitor run
|
||||
JobRegistryMonitorHelper.getInstance().start();
|
||||
|
||||
// admin monitor run
|
||||
JobFailMonitorHelper.getInstance().start();
|
||||
|
||||
// rpc-service, base on spring-mvc
|
||||
NetComServerFactory.putService(AdminBiz.class, XxlJobDynamicScheduler.adminBiz);
|
||||
// accessToken
|
||||
private static String accessToken;
|
||||
public void setAccessToken(String accessToken) {
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
|
||||
// destroy
|
||||
public void destroy(){
|
||||
// admin registry stop
|
||||
JobRegistryMonitorHelper.getInstance().toStop();
|
||||
|
||||
// admin monitor stop
|
||||
JobFailMonitorHelper.getInstance().toStop();
|
||||
}
|
||||
|
||||
// xxlJobLogDao、xxlJobInfoDao
|
||||
// dao
|
||||
public static XxlJobLogDao xxlJobLogDao;
|
||||
public static XxlJobInfoDao xxlJobInfoDao;
|
||||
public static XxlJobRegistryDao xxlJobRegistryDao;
|
||||
public static XxlJobGroupDao xxlJobGroupDao;
|
||||
public static AdminBiz adminBiz;
|
||||
|
||||
// ---------------------- applicationContext ----------------------
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
XxlJobDynamicScheduler.xxlJobLogDao = applicationContext.getBean(XxlJobLogDao.class);
|
||||
|
@ -73,48 +63,60 @@ public final class XxlJobDynamicScheduler implements ApplicationContextAware, In
|
|||
XxlJobDynamicScheduler.xxlJobGroupDao = applicationContext.getBean(XxlJobGroupDao.class);
|
||||
XxlJobDynamicScheduler.adminBiz = applicationContext.getBean(AdminBiz.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
|
||||
// ---------------------- init + destroy ----------------------
|
||||
public void init() throws Exception {
|
||||
// admin registry monitor run
|
||||
JobRegistryMonitorHelper.getInstance().start();
|
||||
|
||||
// admin monitor run
|
||||
JobFailMonitorHelper.getInstance().start();
|
||||
|
||||
// admin-server(spring-mvc)
|
||||
NetComServerFactory.putService(AdminBiz.class, XxlJobDynamicScheduler.adminBiz);
|
||||
NetComServerFactory.setAccessToken(accessToken);
|
||||
|
||||
// valid
|
||||
Assert.notNull(scheduler, "quartz scheduler is null");
|
||||
logger.info(">>>>>>>>> init quartz scheduler success.[{}]", scheduler);
|
||||
|
||||
}
|
||||
|
||||
// getJobKeys
|
||||
@Deprecated
|
||||
public static List<Map<String, Object>> getJobList(){
|
||||
List<Map<String, Object>> jobList = new ArrayList<Map<String,Object>>();
|
||||
|
||||
try {
|
||||
if (scheduler.getJobGroupNames()==null || scheduler.getJobGroupNames().size()==0) {
|
||||
return null;
|
||||
}
|
||||
String groupName = scheduler.getJobGroupNames().get(0);
|
||||
Set<JobKey> jobKeys = scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName));
|
||||
if (jobKeys!=null && jobKeys.size()>0) {
|
||||
for (JobKey jobKey : jobKeys) {
|
||||
TriggerKey triggerKey = TriggerKey.triggerKey(jobKey.getName(), Scheduler.DEFAULT_GROUP);
|
||||
Trigger trigger = scheduler.getTrigger(triggerKey);
|
||||
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
|
||||
TriggerState triggerState = scheduler.getTriggerState(triggerKey);
|
||||
Map<String, Object> jobMap = new HashMap<String, Object>();
|
||||
jobMap.put("TriggerKey", triggerKey);
|
||||
jobMap.put("Trigger", trigger);
|
||||
jobMap.put("JobDetail", jobDetail);
|
||||
jobMap.put("TriggerState", triggerState);
|
||||
jobList.add(jobMap);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (SchedulerException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
return jobList;
|
||||
}
|
||||
|
||||
// fill job info
|
||||
|
||||
public void destroy(){
|
||||
// admin registry stop
|
||||
JobRegistryMonitorHelper.getInstance().toStop();
|
||||
|
||||
// admin monitor stop
|
||||
JobFailMonitorHelper.getInstance().toStop();
|
||||
}
|
||||
|
||||
// ---------------------- executor-client ----------------------
|
||||
private static ConcurrentHashMap<String, ExecutorBiz> executorBizRepository = new ConcurrentHashMap<String, ExecutorBiz>();
|
||||
public static ExecutorBiz getExecutorBiz(String address) throws Exception {
|
||||
// valid
|
||||
if (address==null || address.trim().length()==0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// load-cache
|
||||
address = address.trim();
|
||||
ExecutorBiz executorBiz = executorBizRepository.get(address);
|
||||
if (executorBiz != null) {
|
||||
return executorBiz;
|
||||
}
|
||||
|
||||
// set-cache
|
||||
executorBiz = (ExecutorBiz) new NetComClientProxy(ExecutorBiz.class, address, accessToken).getObject();
|
||||
executorBizRepository.put(address, executorBiz);
|
||||
return executorBiz;
|
||||
}
|
||||
|
||||
// ---------------------- schedule util ----------------------
|
||||
|
||||
/**
|
||||
* fill job info
|
||||
*
|
||||
* @param jobInfo
|
||||
*/
|
||||
public static void fillJobInfo(XxlJobInfo jobInfo) {
|
||||
// TriggerKey : name + group
|
||||
String group = String.valueOf(jobInfo.getJobGroup());
|
||||
|
@ -145,14 +147,28 @@ public final class XxlJobDynamicScheduler implements ApplicationContextAware, In
|
|||
}
|
||||
}
|
||||
|
||||
// check if exists
|
||||
/**
|
||||
* check if exists
|
||||
*
|
||||
* @param jobName
|
||||
* @param jobGroup
|
||||
* @return
|
||||
* @throws SchedulerException
|
||||
*/
|
||||
public static boolean checkExists(String jobName, String jobGroup) throws SchedulerException{
|
||||
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
|
||||
return scheduler.checkExists(triggerKey);
|
||||
}
|
||||
|
||||
// addJob 新增
|
||||
@SuppressWarnings("unchecked")
|
||||
/**
|
||||
* addJob
|
||||
*
|
||||
* @param jobName
|
||||
* @param jobGroup
|
||||
* @param cronExpression
|
||||
* @return
|
||||
* @throws SchedulerException
|
||||
*/
|
||||
public static boolean addJob(String jobName, String jobGroup, String cronExpression) throws SchedulerException {
|
||||
// TriggerKey : name + group
|
||||
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
|
||||
|
@ -185,7 +201,15 @@ public final class XxlJobDynamicScheduler implements ApplicationContextAware, In
|
|||
return true;
|
||||
}
|
||||
|
||||
// reschedule
|
||||
/**
|
||||
* rescheduleJob
|
||||
*
|
||||
* @param jobGroup
|
||||
* @param jobName
|
||||
* @param cronExpression
|
||||
* @return
|
||||
* @throws SchedulerException
|
||||
*/
|
||||
public static boolean rescheduleJob(String jobGroup, String jobName, String cronExpression) throws SchedulerException {
|
||||
|
||||
// TriggerKey valid if_exists
|
||||
|
@ -234,7 +258,14 @@ public final class XxlJobDynamicScheduler implements ApplicationContextAware, In
|
|||
return true;
|
||||
}
|
||||
|
||||
// unscheduleJob
|
||||
/**
|
||||
* unscheduleJob
|
||||
*
|
||||
* @param jobName
|
||||
* @param jobGroup
|
||||
* @return
|
||||
* @throws SchedulerException
|
||||
*/
|
||||
public static boolean removeJob(String jobName, String jobGroup) throws SchedulerException {
|
||||
// TriggerKey : name + group
|
||||
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
|
||||
|
@ -246,7 +277,14 @@ public final class XxlJobDynamicScheduler implements ApplicationContextAware, In
|
|||
return true;
|
||||
}
|
||||
|
||||
// Pause
|
||||
/**
|
||||
* pause
|
||||
*
|
||||
* @param jobName
|
||||
* @param jobGroup
|
||||
* @return
|
||||
* @throws SchedulerException
|
||||
*/
|
||||
public static boolean pauseJob(String jobName, String jobGroup) throws SchedulerException {
|
||||
// TriggerKey : name + group
|
||||
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
|
||||
|
@ -262,7 +300,14 @@ public final class XxlJobDynamicScheduler implements ApplicationContextAware, In
|
|||
return result;
|
||||
}
|
||||
|
||||
// resume
|
||||
/**
|
||||
* resume
|
||||
*
|
||||
* @param jobName
|
||||
* @param jobGroup
|
||||
* @return
|
||||
* @throws SchedulerException
|
||||
*/
|
||||
public static boolean resumeJob(String jobName, String jobGroup) throws SchedulerException {
|
||||
// TriggerKey : name + group
|
||||
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
|
||||
|
@ -278,7 +323,14 @@ public final class XxlJobDynamicScheduler implements ApplicationContextAware, In
|
|||
return result;
|
||||
}
|
||||
|
||||
// run
|
||||
/**
|
||||
* run
|
||||
*
|
||||
* @param jobName
|
||||
* @param jobGroup
|
||||
* @return
|
||||
* @throws SchedulerException
|
||||
*/
|
||||
public static boolean triggerJob(String jobName, String jobGroup) throws SchedulerException {
|
||||
// TriggerKey : name + group
|
||||
JobKey jobKey = new JobKey(jobName, jobGroup);
|
||||
|
@ -294,5 +346,41 @@ public final class XxlJobDynamicScheduler implements ApplicationContextAware, In
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* finaAllJobList
|
||||
*
|
||||
* @return
|
||||
*//*
|
||||
@Deprecated
|
||||
public static List<Map<String, Object>> finaAllJobList(){
|
||||
List<Map<String, Object>> jobList = new ArrayList<Map<String,Object>>();
|
||||
|
||||
try {
|
||||
if (scheduler.getJobGroupNames()==null || scheduler.getJobGroupNames().size()==0) {
|
||||
return null;
|
||||
}
|
||||
String groupName = scheduler.getJobGroupNames().get(0);
|
||||
Set<JobKey> jobKeys = scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName));
|
||||
if (jobKeys!=null && jobKeys.size()>0) {
|
||||
for (JobKey jobKey : jobKeys) {
|
||||
TriggerKey triggerKey = TriggerKey.triggerKey(jobKey.getName(), Scheduler.DEFAULT_GROUP);
|
||||
Trigger trigger = scheduler.getTrigger(triggerKey);
|
||||
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
|
||||
TriggerState triggerState = scheduler.getTriggerState(triggerKey);
|
||||
Map<String, Object> jobMap = new HashMap<String, Object>();
|
||||
jobMap.put("TriggerKey", triggerKey);
|
||||
jobMap.put("Trigger", trigger);
|
||||
jobMap.put("JobDetail", jobDetail);
|
||||
jobMap.put("TriggerState", triggerState);
|
||||
jobList.add(jobMap);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (SchedulerException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
return jobList;
|
||||
}*/
|
||||
|
||||
}
|
|
@ -30,7 +30,7 @@ public class JobFailMonitorHelper {
|
|||
private LinkedBlockingQueue<Integer> queue = new LinkedBlockingQueue<Integer>(0xfff8);
|
||||
|
||||
private Thread monitorThread;
|
||||
private boolean toStop = false;
|
||||
private volatile boolean toStop = false;
|
||||
public void start(){
|
||||
monitorThread = new Thread(new Runnable() {
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ public class JobRegistryMonitorHelper {
|
|||
}
|
||||
|
||||
private Thread registryThread;
|
||||
private boolean toStop = false;
|
||||
private volatile boolean toStop = false;
|
||||
public void start(){
|
||||
registryThread = new Thread(new Runnable() {
|
||||
@Override
|
||||
|
|
|
@ -5,9 +5,9 @@ import com.xxl.job.admin.core.model.XxlJobGroup;
|
|||
import com.xxl.job.admin.core.model.XxlJobInfo;
|
||||
import com.xxl.job.admin.core.model.XxlJobLog;
|
||||
import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum;
|
||||
import com.xxl.job.admin.core.route.ExecutorRouter;
|
||||
import com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler;
|
||||
import com.xxl.job.admin.core.thread.JobFailMonitorHelper;
|
||||
import com.xxl.job.core.biz.ExecutorBiz;
|
||||
import com.xxl.job.core.biz.model.ReturnT;
|
||||
import com.xxl.job.core.biz.model.TriggerParam;
|
||||
import com.xxl.job.core.enums.ExecutorBlockStrategyEnum;
|
||||
|
@ -90,12 +90,12 @@ public class XxlJobTrigger {
|
|||
triggerParam.setBroadcastTotal(addressList.size()); // update02
|
||||
|
||||
// 4.2、trigger-run (route run / trigger remote executor)
|
||||
triggerResult = ExecutorRouter.runExecutor(triggerParam, address); // update03
|
||||
triggerResult = runExecutor(triggerParam, address); // update03
|
||||
triggerMsgSb.append("<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>").append(triggerResult.getMsg());
|
||||
|
||||
// 4.3、trigger (fail retry)
|
||||
if (triggerResult.getCode()!=ReturnT.SUCCESS_CODE && failStrategy == ExecutorFailStrategyEnum.FAIL_RETRY) {
|
||||
triggerResult = ExecutorRouter.runExecutor(triggerParam, address); // update04
|
||||
triggerResult = runExecutor(triggerParam, address); // update04
|
||||
triggerMsgSb.append("<br><br><span style=\"color:#F39C12;\" > >>>>>>>>>>>失败重试<<<<<<<<<<< </span><br>").append(triggerResult.getMsg());
|
||||
}
|
||||
}
|
||||
|
@ -179,4 +179,30 @@ public class XxlJobTrigger {
|
|||
logger.debug(">>>>>>>>>>> xxl-job trigger end, jobId:{}", jobLog.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* run executor
|
||||
* @param triggerParam
|
||||
* @param address
|
||||
* @return ReturnT.content: final address
|
||||
*/
|
||||
public static ReturnT<String> runExecutor(TriggerParam triggerParam, String address){
|
||||
ReturnT<String> runResult = null;
|
||||
try {
|
||||
ExecutorBiz executorBiz = XxlJobDynamicScheduler.getExecutorBiz(address);
|
||||
runResult = executorBiz.run(triggerParam);
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
runResult = new ReturnT<String>(ReturnT.FAIL_CODE, ""+e );
|
||||
}
|
||||
|
||||
StringBuffer runResultSB = new StringBuffer("触发调度:");
|
||||
runResultSB.append("<br>address:").append(address);
|
||||
runResultSB.append("<br>code:").append(runResult.getCode());
|
||||
runResultSB.append("<br>msg:").append(runResult.getMsg());
|
||||
|
||||
runResult.setMsg(runResultSB.toString());
|
||||
runResult.setContent(address);
|
||||
return runResult;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
<bean id="xxlJobDynamicScheduler" class="com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler" init-method="init" destroy-method="destroy" >
|
||||
<!-- (轻易不要变更“调度器名称”, 任务创建时会绑定该“调度器名称”) -->
|
||||
<property name="scheduler" ref="quartzScheduler"/>
|
||||
<property name="accessToken" value="${xxl.job.accessToken}" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
|
@ -12,6 +12,9 @@ xxl.job.mail.password=asdfzxcv
|
|||
xxl.job.mail.sendFrom=ovono802302@163.com
|
||||
xxl.job.mail.sendNick=《任务调度平台XXL-JOB》
|
||||
|
||||
# xxl-job login
|
||||
### xxl-job login
|
||||
xxl.job.login.username=admin
|
||||
xxl.job.login.password=123456
|
||||
xxl.job.login.password=123456
|
||||
|
||||
### xxl-job, access token
|
||||
xxl.job.accessToken=
|
|
@ -175,11 +175,12 @@
|
|||
|
||||
<#macro commonFooter >
|
||||
<footer class="main-footer">
|
||||
Powered by <b>XXL-JOB</b> 1.8.1(快照版)
|
||||
Powered by <b>XXL-JOB</b> 1.8.2(快照版本)
|
||||
<div class="pull-right hidden-xs">
|
||||
<strong>Copyright © 2015-${.now?string('yyyy')}
|
||||
<a href="https://github.com/xuxueli/xxl-job" target="_blank" >github</a>
|
||||
<a href="http://my.oschina.net/xuxueli/blog/690978" target="_blank" >oschina</a>
|
||||
<a href="http://www.xuxueli.com/" target="_blank" >xuxueli</a>
|
||||
|
||||
<a href="https://github.com/xuxueli/xxl-job" target="_blank" >github</a>
|
||||
</strong><!-- All rights reserved. -->
|
||||
</div>
|
||||
</footer>
|
||||
|
|
|
@ -31,33 +31,14 @@
|
|||
<h4>简介:XXL-JOB</h4>
|
||||
<br>
|
||||
<p>
|
||||
<a target="_blank" href="https://github.com/xuxueli/xxl-job">github地址</a>
|
||||
<a target="_blank" href="http://www.xuxueli.com/">xuxueli</a>
|
||||
<br><br>
|
||||
<a target="_blank" href="https://github.com/xuxueli/xxl-job">github</a>
|
||||
<iframe src="https://ghbtns.com/github-btn.html?user=xuxueli&repo=xxl-job&type=star&count=true" frameborder="0" scrolling="0" width="170px" height="20px" style="margin-bottom:-5px;"></iframe>
|
||||
<br><br>
|
||||
<a target="_blank" href="http://my.oschina.net/xuxueli/blog/690978">oschina地址</a>
|
||||
<a target="_blank" href="http://my.oschina.net/xuxueli/blog/690978">oschina(文档中有交流群)</a>
|
||||
<br><br>
|
||||
|
||||
<a >技术交流群5:138274130</a>
|
||||
<a target="_blank" href="//shang.qq.com/wpa/qunwpa?idkey=a3f3aea7e5943e7a24e9726495747ddc19bccd3592d7a70ecb5a97b616062241">
|
||||
<img border="0" src="//pub.idqqimg.com/wpa/images/group.png" alt="《xxl-javaer》(五群)" title="《xxl-javaer》(五群)">
|
||||
</a>
|
||||
<br><br>
|
||||
|
||||
<a >技术交流群4:464762661</a>
|
||||
(群即将满,请加群5)
|
||||
<br><br>
|
||||
|
||||
<a >技术交流群3:242151780</a>
|
||||
(群即将满,请加群5)
|
||||
<br><br>
|
||||
|
||||
<a >技术交流群2:438249535</a>
|
||||
(群即将满,请加群5)
|
||||
<br><br>
|
||||
|
||||
<a >技术交流群1:367260654</a>
|
||||
(群即将满,请加群5)
|
||||
|
||||
</p>
|
||||
<p></p>
|
||||
</div>
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
<span class="input-group-addon">执行器</span>
|
||||
<select class="form-control" id="jobGroup" >
|
||||
<#list JobGroupList as group>
|
||||
<option value="${group.id}" >${group.title}</option>
|
||||
<option value="${group.id}" <#if jobGroup==group.id>selected</#if> >${group.title}</option>
|
||||
</#list>
|
||||
</select>
|
||||
</div>
|
||||
|
@ -110,7 +110,7 @@
|
|||
<div class="col-sm-4">
|
||||
<select class="form-control" name="jobGroup" >
|
||||
<#list JobGroupList as group>
|
||||
<option value="${group.id}" >${group.title}</option>
|
||||
<option value="${group.id}" <#if jobGroup==group.id>selected</#if> >${group.title}</option>
|
||||
</#list>
|
||||
</select>
|
||||
</div>
|
||||
|
|
|
@ -167,6 +167,13 @@ $(function() {
|
|||
jobTable.fnDraw();
|
||||
});
|
||||
|
||||
// jobGroup change
|
||||
$('#jobGroup').on('change', function(){
|
||||
//reload
|
||||
var jobGroup = $('#jobGroup').val();
|
||||
window.location.href = base_url + "/jobinfo?jobGroup=" + jobGroup;
|
||||
});
|
||||
|
||||
// job operate
|
||||
$("#job_list").on('click', '.job_operate',function() {
|
||||
var typeName;
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package com.xxl.job.dao.impl;
|
||||
|
||||
import com.xxl.job.core.biz.AdminBiz;
|
||||
import com.xxl.job.core.biz.model.RegistryParam;
|
||||
import com.xxl.job.core.biz.model.ReturnT;
|
||||
import com.xxl.job.core.enums.RegistryConfig;
|
||||
import com.xxl.job.core.rpc.netcom.NetComClientProxy;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* admin-api client, test
|
||||
* @author xuxueli 2017-07-28 22:14:52
|
||||
*/
|
||||
public class AdminBizTest {
|
||||
|
||||
@Test
|
||||
public void registryTest() throws Exception {
|
||||
|
||||
// admin-client
|
||||
String addressUrl = "http://127.0.0.1:8080/xxl-job-admin".concat(AdminBiz.MAPPING);
|
||||
String accessToken = null;
|
||||
AdminBiz adminBiz = (AdminBiz) new NetComClientProxy(AdminBiz.class, addressUrl, accessToken).getObject();
|
||||
|
||||
// test executor registry
|
||||
RegistryParam registryParam = new RegistryParam(RegistryConfig.RegistType.EXECUTOR.name(), "xxl-job-executor-example", "127.0.0.1:9999");
|
||||
ReturnT<String> returnT = adminBiz.registry(registryParam);
|
||||
Assert.assertTrue(returnT.getCode() == ReturnT.SUCCESS_CODE);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>com.xuxueli</groupId>
|
||||
<artifactId>xxl-job</artifactId>
|
||||
<version>1.8.1-SNAPSHOT</version>
|
||||
<version>1.8.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>xxl-job-core</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
@ -13,56 +13,52 @@
|
|||
<description>A lightweight distributed task scheduling framework.</description>
|
||||
<url>http://www.xuxueli.com/</url>
|
||||
|
||||
<properties>
|
||||
<spring.version>3.2.17.RELEASE</spring.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- servlet -->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>3.0.1</version>
|
||||
<version>${javax.servlet-api.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet.jsp</groupId>
|
||||
<artifactId>jsp-api</artifactId>
|
||||
<version>2.2</version>
|
||||
<version>${jsp-api.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- jetty -->
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
<version>9.2.21.v20170120</version>
|
||||
<version>${jetty-server.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- slf4j -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.21</version>
|
||||
<version>${slf4j-api.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- hessian -->
|
||||
<dependency>
|
||||
<groupId>com.caucho</groupId>
|
||||
<artifactId>hessian</artifactId>
|
||||
<version>4.0.38</version>
|
||||
<version>${hessian.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- jackson -->
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-mapper-asl</artifactId>
|
||||
<version>1.9.13</version>
|
||||
<version>${jackson-mapper-asl.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- httpclient -->
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.3.6</version>
|
||||
<version>${httpclient.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- spring-context -->
|
||||
|
@ -76,14 +72,14 @@
|
|||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-all</artifactId>
|
||||
<version>2.4.5</version>
|
||||
<version>${groovy-all.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- commons-exec -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-exec</artifactId>
|
||||
<version>1.3</version>
|
||||
<version>${commons-exec.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
|
|
@ -11,6 +11,8 @@ import java.util.List;
|
|||
*/
|
||||
public interface AdminBiz {
|
||||
|
||||
public static final String MAPPING = "/api";
|
||||
|
||||
/**
|
||||
* callback
|
||||
*
|
||||
|
|
|
@ -1,36 +1,38 @@
|
|||
package com.xxl.job.core.executor;
|
||||
|
||||
import com.xxl.job.core.biz.AdminBiz;
|
||||
import com.xxl.job.core.biz.ExecutorBiz;
|
||||
import com.xxl.job.core.biz.impl.ExecutorBizImpl;
|
||||
import com.xxl.job.core.handler.IJobHandler;
|
||||
import com.xxl.job.core.handler.annotation.JobHander;
|
||||
import com.xxl.job.core.log.XxlJobFileAppender;
|
||||
import com.xxl.job.core.rpc.netcom.NetComClientProxy;
|
||||
import com.xxl.job.core.rpc.netcom.NetComServerFactory;
|
||||
import com.xxl.job.core.thread.ExecutorRegistryThread;
|
||||
import com.xxl.job.core.thread.JobThread;
|
||||
import com.xxl.job.core.thread.TriggerCallbackThread;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.event.ContextClosedEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Created by xuxueli on 2016/3/2 21:14.
|
||||
*/
|
||||
public class XxlJobExecutor implements ApplicationContextAware, ApplicationListener {
|
||||
public class XxlJobExecutor implements ApplicationContextAware {
|
||||
private static final Logger logger = LoggerFactory.getLogger(XxlJobExecutor.class);
|
||||
|
||||
// ---------------------- param ----------------------
|
||||
private String ip;
|
||||
private int port = 9999;
|
||||
private String appName;
|
||||
public static String adminAddresses;
|
||||
public static String logPath;
|
||||
private String adminAddresses;
|
||||
private String accessToken;
|
||||
private String logPath;
|
||||
|
||||
public void setIp(String ip) {
|
||||
this.ip = ip;
|
||||
|
@ -44,48 +46,98 @@ public class XxlJobExecutor implements ApplicationContextAware, ApplicationListe
|
|||
public void setAdminAddresses(String adminAddresses) {
|
||||
this.adminAddresses = adminAddresses;
|
||||
}
|
||||
public void setAccessToken(String accessToken) {
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
public void setLogPath(String logPath) {
|
||||
this.logPath = logPath;
|
||||
}
|
||||
|
||||
// ---------------------------------- job server ------------------------------------
|
||||
private NetComServerFactory serverFactory = new NetComServerFactory();
|
||||
public void start() throws Exception {
|
||||
// executor start
|
||||
NetComServerFactory.putService(ExecutorBiz.class, new ExecutorBizImpl()); // rpc-service, base on jetty
|
||||
serverFactory.start(port, ip, appName);
|
||||
|
||||
// trigger callback thread start
|
||||
TriggerCallbackThread.getInstance().start();
|
||||
// ---------------------- applicationContext ----------------------
|
||||
private static ApplicationContext applicationContext;
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
public static ApplicationContext getApplicationContext() {
|
||||
return applicationContext;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------- start + stop ----------------------
|
||||
public void start() throws Exception {
|
||||
// init admin-client
|
||||
initAdminBizList(adminAddresses, accessToken);
|
||||
|
||||
// init executor-jobHandlerRepository
|
||||
initJobHandlerRepository(applicationContext);
|
||||
|
||||
// init logpath
|
||||
if (logPath!=null && logPath.trim().length()>0) {
|
||||
XxlJobFileAppender.logPath = logPath;
|
||||
}
|
||||
|
||||
// init executor-server
|
||||
initExecutorServer(port, ip, appName, accessToken);
|
||||
}
|
||||
public void destroy(){
|
||||
// 1、executor registry thread stop
|
||||
ExecutorRegistryThread.getInstance().toStop();
|
||||
|
||||
// 2、executor stop
|
||||
serverFactory.destroy();
|
||||
|
||||
// 3、job thread repository destory
|
||||
// destory JobThreadRepository
|
||||
if (JobThreadRepository.size() > 0) {
|
||||
for (Map.Entry<Integer, JobThread> item: JobThreadRepository.entrySet()) {
|
||||
JobThread jobThread = item.getValue();
|
||||
jobThread.toStop("Web容器销毁终止");
|
||||
jobThread.interrupt();
|
||||
|
||||
removeJobThread(item.getKey(), "Web容器销毁终止");
|
||||
}
|
||||
JobThreadRepository.clear();
|
||||
}
|
||||
|
||||
// 4、trigger callback thread stop
|
||||
TriggerCallbackThread.getInstance().toStop();
|
||||
// destory executor-server
|
||||
stopExecutorServer();
|
||||
}
|
||||
|
||||
// ---------------------------------- init job handler ------------------------------------
|
||||
public static ApplicationContext applicationContext;
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
XxlJobExecutor.applicationContext = applicationContext;
|
||||
|
||||
// ---------------------- admin-client ----------------------
|
||||
private static List<AdminBiz> adminBizList;
|
||||
private static void initAdminBizList(String adminAddresses, String accessToken) throws Exception {
|
||||
if (adminAddresses!=null && adminAddresses.trim().length()>0) {
|
||||
for (String address: adminAddresses.trim().split(",")) {
|
||||
if (address!=null && address.trim().length()>0) {
|
||||
String addressUrl = address.concat(AdminBiz.MAPPING);
|
||||
AdminBiz adminBiz = (AdminBiz) new NetComClientProxy(AdminBiz.class, addressUrl, accessToken).getObject();
|
||||
if (adminBizList == null) {
|
||||
adminBizList = new ArrayList<AdminBiz>();
|
||||
}
|
||||
adminBizList.add(adminBiz);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public static List<AdminBiz> getAdminBizList(){
|
||||
return adminBizList;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------- executor-server(jetty) ----------------------
|
||||
private NetComServerFactory serverFactory = new NetComServerFactory();
|
||||
private void initExecutorServer(int port, String ip, String appName, String accessToken) throws Exception {
|
||||
NetComServerFactory.putService(ExecutorBiz.class, new ExecutorBizImpl()); // rpc-service, base on jetty
|
||||
NetComServerFactory.setAccessToken(accessToken);
|
||||
serverFactory.start(port, ip, appName); // jetty + registry
|
||||
}
|
||||
private void stopExecutorServer() {
|
||||
serverFactory.destroy(); // jetty + registry + callback
|
||||
}
|
||||
|
||||
|
||||
// ---------------------- job handler repository ----------------------
|
||||
private static ConcurrentHashMap<String, IJobHandler> jobHandlerRepository = new ConcurrentHashMap<String, IJobHandler>();
|
||||
public static IJobHandler registJobHandler(String name, IJobHandler jobHandler){
|
||||
logger.info("xxl-job register jobhandler success, name:{}, jobHandler:{}", name, jobHandler);
|
||||
return jobHandlerRepository.put(name, jobHandler);
|
||||
}
|
||||
public static IJobHandler loadJobHandler(String name){
|
||||
return jobHandlerRepository.get(name);
|
||||
}
|
||||
private static void initJobHandlerRepository(ApplicationContext applicationContext){
|
||||
// init job handler action
|
||||
Map<String, Object> serviceBeanMap = applicationContext.getBeansWithAnnotation(JobHander.class);
|
||||
|
||||
|
@ -101,27 +153,10 @@ public class XxlJobExecutor implements ApplicationContextAware, ApplicationListe
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------- destory job executor ------------------------------------
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationEvent applicationEvent) {
|
||||
if(applicationEvent instanceof ContextClosedEvent){
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------- job handler repository
|
||||
private static ConcurrentHashMap<String, IJobHandler> jobHandlerRepository = new ConcurrentHashMap<String, IJobHandler>();
|
||||
public static IJobHandler registJobHandler(String name, IJobHandler jobHandler){
|
||||
logger.info("xxl-job register jobhandler success, name:{}, jobHandler:{}", name, jobHandler);
|
||||
return jobHandlerRepository.put(name, jobHandler);
|
||||
}
|
||||
public static IJobHandler loadJobHandler(String name){
|
||||
return jobHandlerRepository.get(name);
|
||||
}
|
||||
|
||||
// ---------------------------------- job thread repository
|
||||
// ---------------------- job thread repository ----------------------
|
||||
private static ConcurrentHashMap<Integer, JobThread> JobThreadRepository = new ConcurrentHashMap<Integer, JobThread>();
|
||||
public static JobThread registJobThread(int jobId, IJobHandler handler, String removeOldReason){
|
||||
JobThread newJobThread = new JobThread(jobId, handler);
|
||||
|
|
|
@ -52,21 +52,21 @@ public class GlueFactory {
|
|||
try {
|
||||
Resource resource = AnnotationUtils.getAnnotation(field, Resource.class);
|
||||
if (resource.name()!=null && resource.name().length()>0){
|
||||
fieldBean = XxlJobExecutor.applicationContext.getBean(resource.name());
|
||||
fieldBean = XxlJobExecutor.getApplicationContext().getBean(resource.name());
|
||||
} else {
|
||||
fieldBean = XxlJobExecutor.applicationContext.getBean(field.getName());
|
||||
fieldBean = XxlJobExecutor.getApplicationContext().getBean(field.getName());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
if (fieldBean==null ) {
|
||||
fieldBean = XxlJobExecutor.applicationContext.getBean(field.getType());
|
||||
fieldBean = XxlJobExecutor.getApplicationContext().getBean(field.getType());
|
||||
}
|
||||
} else if (AnnotationUtils.getAnnotation(field, Autowired.class) != null) {
|
||||
Qualifier qualifier = AnnotationUtils.getAnnotation(field, Qualifier.class);
|
||||
if (qualifier!=null && qualifier.value()!=null && qualifier.value().length()>0) {
|
||||
fieldBean = XxlJobExecutor.applicationContext.getBean(qualifier.value());
|
||||
fieldBean = XxlJobExecutor.getApplicationContext().getBean(qualifier.value());
|
||||
} else {
|
||||
fieldBean = XxlJobExecutor.applicationContext.getBean(field.getType());
|
||||
fieldBean = XxlJobExecutor.getApplicationContext().getBean(field.getType());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package com.xxl.job.core.handler.impl;
|
||||
|
||||
import com.xxl.job.core.biz.model.ReturnT;
|
||||
import com.xxl.job.core.executor.XxlJobExecutor;
|
||||
import com.xxl.job.core.glue.GlueTypeEnum;
|
||||
import com.xxl.job.core.handler.IJobHandler;
|
||||
import com.xxl.job.core.log.XxlJobFileAppender;
|
||||
|
@ -37,17 +36,17 @@ public class ScriptJobHandler extends IJobHandler {
|
|||
String scriptFileName = null;
|
||||
if (GlueTypeEnum.GLUE_SHELL == glueType) {
|
||||
cmd = "bash";
|
||||
scriptFileName = XxlJobExecutor.logPath.concat("gluesource/").concat(String.valueOf(jobId)).concat("_").concat(String.valueOf(glueUpdatetime)).concat(".sh");
|
||||
scriptFileName = XxlJobFileAppender.logPath.concat("gluesource/").concat(String.valueOf(jobId)).concat("_").concat(String.valueOf(glueUpdatetime)).concat(".sh");
|
||||
} else if (GlueTypeEnum.GLUE_PYTHON == glueType) {
|
||||
cmd = "python";
|
||||
scriptFileName = XxlJobExecutor.logPath.concat("gluesource/").concat(String.valueOf(jobId)).concat("_").concat(String.valueOf(glueUpdatetime)).concat(".py");
|
||||
scriptFileName = XxlJobFileAppender.logPath.concat("gluesource/").concat(String.valueOf(jobId)).concat("_").concat(String.valueOf(glueUpdatetime)).concat(".py");
|
||||
}
|
||||
|
||||
// make script file
|
||||
ScriptUtil.markScriptFile(scriptFileName, gluesource);
|
||||
|
||||
// log file
|
||||
String logFileName = XxlJobExecutor.logPath.concat(XxlJobFileAppender.contextHolder.get());
|
||||
String logFileName = XxlJobFileAppender.logPath.concat(XxlJobFileAppender.contextHolder.get());
|
||||
|
||||
// invoke
|
||||
XxlJobLogger.log("----------- script file:"+ scriptFileName +" -----------");
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package com.xxl.job.core.log;
|
||||
|
||||
import com.xxl.job.core.biz.model.LogResult;
|
||||
import com.xxl.job.core.executor.XxlJobExecutor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -20,7 +19,8 @@ public class XxlJobFileAppender {
|
|||
//public static ThreadLocal<String> contextHolder = new ThreadLocal<String>();
|
||||
public static final InheritableThreadLocal<String> contextHolder = new InheritableThreadLocal<String>();
|
||||
public static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||
|
||||
public static String logPath = "/data/applogs/xxl-job/jobhandler/";
|
||||
|
||||
/**
|
||||
* log filename: yyyy-MM-dd/9999.log
|
||||
*
|
||||
|
@ -31,7 +31,7 @@ public class XxlJobFileAppender {
|
|||
public static String makeLogFileName(Date triggerDate, int logId) {
|
||||
|
||||
// filePath/
|
||||
File filePathDir = new File(XxlJobExecutor.logPath);
|
||||
File filePathDir = new File(logPath);
|
||||
if (!filePathDir.exists()) {
|
||||
filePathDir.mkdirs();
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ public class XxlJobFileAppender {
|
|||
if (logFileName==null || logFileName.trim().length()==0) {
|
||||
return;
|
||||
}
|
||||
File logFile = new File(XxlJobExecutor.logPath, logFileName);
|
||||
File logFile = new File(logPath, logFileName);
|
||||
|
||||
if (!logFile.exists()) {
|
||||
try {
|
||||
|
@ -111,7 +111,7 @@ public class XxlJobFileAppender {
|
|||
if (logFileName==null || logFileName.trim().length()==0) {
|
||||
return new LogResult(fromLineNum, 0, "readLog fail, logFile not found", true);
|
||||
}
|
||||
File logFile = new File(XxlJobExecutor.logPath, logFileName);
|
||||
File logFile = new File(logPath, logFileName);
|
||||
|
||||
if (!logFile.exists()) {
|
||||
return new LogResult(fromLineNum, 0, "readLog fail, logFile not exists", true);
|
||||
|
|
|
@ -12,12 +12,14 @@ public class RpcRequest implements Serializable{
|
|||
|
||||
private String serverAddress;
|
||||
private long createMillisTime;
|
||||
private String accessToken;
|
||||
|
||||
private String className;
|
||||
private String methodName;
|
||||
private Class<?>[] parameterTypes;
|
||||
private Object[] parameters;
|
||||
|
||||
|
||||
public String getServerAddress() {
|
||||
return serverAddress;
|
||||
}
|
||||
|
@ -29,41 +31,62 @@ public class RpcRequest implements Serializable{
|
|||
public long getCreateMillisTime() {
|
||||
return createMillisTime;
|
||||
}
|
||||
|
||||
public void setCreateMillisTime(long createMillisTime) {
|
||||
this.createMillisTime = createMillisTime;
|
||||
}
|
||||
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public void setAccessToken(String accessToken) {
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
public void setClassName(String className) {
|
||||
this.className = className;
|
||||
}
|
||||
|
||||
public String getMethodName() {
|
||||
return methodName;
|
||||
}
|
||||
|
||||
public void setMethodName(String methodName) {
|
||||
this.methodName = methodName;
|
||||
}
|
||||
|
||||
public Class<?>[] getParameterTypes() {
|
||||
return parameterTypes;
|
||||
}
|
||||
|
||||
public void setParameterTypes(Class<?>[] parameterTypes) {
|
||||
this.parameterTypes = parameterTypes;
|
||||
}
|
||||
|
||||
public Object[] getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public void setParameters(Object[] parameters) {
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NettyRequest [serverAddress=" + serverAddress + ", createMillisTime="
|
||||
+ createMillisTime + ", className=" + className
|
||||
+ ", methodName=" + methodName + ", parameterTypes="
|
||||
+ Arrays.toString(parameterTypes) + ", parameters="
|
||||
+ Arrays.toString(parameters) + "]";
|
||||
return "RpcRequest{" +
|
||||
"serverAddress='" + serverAddress + '\'' +
|
||||
", createMillisTime=" + createMillisTime +
|
||||
", accessToken='" + accessToken + '\'' +
|
||||
", className='" + className + '\'' +
|
||||
", methodName='" + methodName + '\'' +
|
||||
", parameterTypes=" + Arrays.toString(parameterTypes) +
|
||||
", parameters=" + Arrays.toString(parameters) +
|
||||
'}';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -20,11 +20,13 @@ public class NetComClientProxy implements FactoryBean<Object> {
|
|||
|
||||
// ---------------------- config ----------------------
|
||||
private Class<?> iface;
|
||||
String serverAddress;
|
||||
JettyClient client = new JettyClient();
|
||||
public NetComClientProxy(Class<?> iface, String serverAddress) {
|
||||
private String serverAddress;
|
||||
private String accessToken;
|
||||
private JettyClient client = new JettyClient();
|
||||
public NetComClientProxy(Class<?> iface, String serverAddress, String accessToken) {
|
||||
this.iface = iface;
|
||||
this.serverAddress = serverAddress;
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -39,6 +41,7 @@ public class NetComClientProxy implements FactoryBean<Object> {
|
|||
RpcRequest request = new RpcRequest();
|
||||
request.setServerAddress(serverAddress);
|
||||
request.setCreateMillisTime(System.currentTimeMillis());
|
||||
request.setAccessToken(accessToken);
|
||||
request.setClassName(method.getDeclaringClass().getName());
|
||||
request.setMethodName(method.getName());
|
||||
request.setParameterTypes(method.getParameterTypes());
|
||||
|
|
|
@ -30,14 +30,18 @@ public class NetComServerFactory {
|
|||
server.destroy();
|
||||
}
|
||||
|
||||
// ---------------------- server init ----------------------
|
||||
// ---------------------- server instance ----------------------
|
||||
/**
|
||||
* init local rpc service map
|
||||
*/
|
||||
private static Map<String, Object> serviceMap = new HashMap<String, Object>();
|
||||
private static String accessToken;
|
||||
public static void putService(Class<?> iface, Object serviceBean){
|
||||
serviceMap.put(iface.getName(), serviceBean);
|
||||
}
|
||||
public static void setAccessToken(String accessToken) {
|
||||
NetComServerFactory.accessToken = accessToken;
|
||||
}
|
||||
public static RpcResponse invokeService(RpcRequest request, Object serviceBean) {
|
||||
if (serviceBean==null) {
|
||||
serviceBean = serviceMap.get(request.getClassName());
|
||||
|
@ -49,7 +53,11 @@ public class NetComServerFactory {
|
|||
RpcResponse response = new RpcResponse();
|
||||
|
||||
if (System.currentTimeMillis() - request.getCreateMillisTime() > 180000) {
|
||||
response.setResult(new ReturnT<String>(ReturnT.FAIL_CODE, "the timestamp difference between admin and executor exceeds the limit."));
|
||||
response.setResult(new ReturnT<String>(ReturnT.FAIL_CODE, "The timestamp difference between admin and executor exceeds the limit."));
|
||||
return response;
|
||||
}
|
||||
if (accessToken!=null && accessToken.trim().length()>0 && !accessToken.trim().equals(request.getAccessToken())) {
|
||||
response.setResult(new ReturnT<String>(ReturnT.FAIL_CODE, "The access token[" + request.getAccessToken() + "] is wrong."));
|
||||
return response;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,8 +21,8 @@ public class JettyClient {
|
|||
|
||||
// reqURL
|
||||
String reqURL = request.getServerAddress();
|
||||
if (reqURL!=null && reqURL.toLowerCase().indexOf("http://")==-1) {
|
||||
reqURL = "http://" + request.getServerAddress() + "/";
|
||||
if (reqURL!=null && reqURL.toLowerCase().indexOf("http")==-1) {
|
||||
reqURL = "http://" + request.getServerAddress() + "/"; // IP:PORT, need parse to url
|
||||
}
|
||||
|
||||
// remote invoke
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.xxl.job.core.rpc.netcom.jetty.server;
|
||||
|
||||
import com.xxl.job.core.thread.ExecutorRegistryThread;
|
||||
import com.xxl.job.core.thread.TriggerCallbackThread;
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
|
@ -38,10 +39,16 @@ public class JettyServer {
|
|||
server.setHandler(handlerc);
|
||||
|
||||
try {
|
||||
// Start the server
|
||||
// Start server
|
||||
server.start();
|
||||
logger.info(">>>>>>>>>>>> xxl-job jetty server start success at port:{}.", port);
|
||||
|
||||
// Start Registry-Server
|
||||
ExecutorRegistryThread.getInstance().start(port, ip, appName);
|
||||
|
||||
// Start Callback-Server
|
||||
TriggerCallbackThread.getInstance().start();
|
||||
|
||||
server.join(); // block until thread stopped
|
||||
logger.info(">>>>>>>>>>> xxl-rpc server join success, netcon={}, port={}", JettyServer.class.getName(), port);
|
||||
} catch (Exception e) {
|
||||
|
@ -56,6 +63,8 @@ public class JettyServer {
|
|||
}
|
||||
|
||||
public void destroy() {
|
||||
|
||||
// destroy server
|
||||
if (server != null) {
|
||||
try {
|
||||
server.stop();
|
||||
|
@ -67,6 +76,13 @@ public class JettyServer {
|
|||
if (thread.isAlive()) {
|
||||
thread.interrupt();
|
||||
}
|
||||
|
||||
// destroy Registry-Server
|
||||
ExecutorRegistryThread.getInstance().toStop();
|
||||
|
||||
// destroy Callback-Server
|
||||
TriggerCallbackThread.getInstance().toStop();
|
||||
|
||||
logger.info(">>>>>>>>>>> xxl-rpc server destroy success, netcon={}", JettyServer.class.getName());
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ import com.xxl.job.core.biz.model.RegistryParam;
|
|||
import com.xxl.job.core.biz.model.ReturnT;
|
||||
import com.xxl.job.core.enums.RegistryConfig;
|
||||
import com.xxl.job.core.executor.XxlJobExecutor;
|
||||
import com.xxl.job.core.rpc.netcom.NetComClientProxy;
|
||||
import com.xxl.job.core.util.IpUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -32,7 +31,7 @@ public class ExecutorRegistryThread extends Thread {
|
|||
logger.warn(">>>>>>>>>>>> xxl-job, executor registry config fail, appName is null.");
|
||||
return;
|
||||
}
|
||||
if (XxlJobExecutor.adminAddresses==null || XxlJobExecutor.adminAddresses.trim().length()==0) {
|
||||
if (XxlJobExecutor.getAdminBizList() == null) {
|
||||
logger.warn(">>>>>>>>>>>> xxl-job, executor registry config fail, adminAddresses is null.");
|
||||
return;
|
||||
}
|
||||
|
@ -49,15 +48,10 @@ public class ExecutorRegistryThread extends Thread {
|
|||
@Override
|
||||
public void run() {
|
||||
while (!toStop) {
|
||||
|
||||
try {
|
||||
RegistryParam registryParam = new RegistryParam(RegistryConfig.RegistType.EXECUTOR.name(), appName, executorAddress);
|
||||
|
||||
for (String addressUrl: XxlJobExecutor.adminAddresses.split(",")) {
|
||||
String apiUrl = addressUrl.concat("/api");
|
||||
|
||||
for (AdminBiz adminBiz: XxlJobExecutor.getAdminBizList()) {
|
||||
try {
|
||||
AdminBiz adminBiz = (AdminBiz) new NetComClientProxy(AdminBiz.class, apiUrl).getObject();
|
||||
ReturnT<String> registryResult = adminBiz.registry(registryParam);
|
||||
if (registryResult!=null && ReturnT.SUCCESS_CODE == registryResult.getCode()) {
|
||||
registryResult = ReturnT.SUCCESS;
|
||||
|
@ -71,7 +65,6 @@ public class ExecutorRegistryThread extends Thread {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import com.xxl.job.core.biz.AdminBiz;
|
|||
import com.xxl.job.core.biz.model.HandleCallbackParam;
|
||||
import com.xxl.job.core.biz.model.ReturnT;
|
||||
import com.xxl.job.core.executor.XxlJobExecutor;
|
||||
import com.xxl.job.core.rpc.netcom.NetComClientProxy;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -43,17 +42,14 @@ public class TriggerCallbackThread {
|
|||
callbackParamList.add(callback);
|
||||
|
||||
// valid
|
||||
if (XxlJobExecutor.adminAddresses==null || XxlJobExecutor.adminAddresses.trim().length()==0) {
|
||||
if (XxlJobExecutor.getAdminBizList()==null) {
|
||||
logger.warn(">>>>>>>>>>>> xxl-job callback fail, adminAddresses is null, callbackParamList:{}", callbackParamList);
|
||||
continue;
|
||||
}
|
||||
|
||||
// callback, will retry if error
|
||||
for (String addressUrl: XxlJobExecutor.adminAddresses.split(",")) {
|
||||
String apiUrl = addressUrl.concat("/api");
|
||||
|
||||
for (AdminBiz adminBiz: XxlJobExecutor.getAdminBizList()) {
|
||||
try {
|
||||
AdminBiz adminBiz = (AdminBiz) new NetComClientProxy(AdminBiz.class, apiUrl).getObject();
|
||||
ReturnT<String> callbackResult = adminBiz.callback(callbackParamList);
|
||||
if (callbackResult!=null && ReturnT.SUCCESS_CODE == callbackResult.getCode()) {
|
||||
callbackResult = ReturnT.SUCCESS;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.xxl.job.core.util;
|
||||
|
||||
import com.xxl.job.core.executor.XxlJobExecutor;
|
||||
import com.xxl.job.core.log.XxlJobFileAppender;
|
||||
import org.apache.commons.exec.CommandLine;
|
||||
import org.apache.commons.exec.DefaultExecutor;
|
||||
import org.apache.commons.exec.PumpStreamHandler;
|
||||
|
@ -28,7 +28,7 @@ public class ScriptUtil {
|
|||
*/
|
||||
public static void markScriptFile(String scriptFileName, String content) throws IOException {
|
||||
// filePath/
|
||||
File filePathDir = new File(XxlJobExecutor.logPath);
|
||||
File filePathDir = new File(XxlJobFileAppender.logPath);
|
||||
if (!filePathDir.exists()) {
|
||||
filePathDir.mkdirs();
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>com.xuxueli</groupId>
|
||||
<artifactId>xxl-job</artifactId>
|
||||
<version>1.8.1-SNAPSHOT</version>
|
||||
<version>1.8.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>xxl-job-executor-example</artifactId>
|
||||
<packaging>war</packaging>
|
||||
|
@ -13,12 +13,8 @@
|
|||
<description>Executor project for spring boot.</description>
|
||||
<url>http://www.xuxueli.com/</url>
|
||||
|
||||
<properties>
|
||||
<spring.version>3.2.17.RELEASE</spring.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- springframe start -->
|
||||
<!-- spring-webmvc -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
|
@ -29,20 +25,7 @@
|
|||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<version>1.7.21</version>
|
||||
</dependency>
|
||||
|
||||
<!-- c3p0 -->
|
||||
<dependency>
|
||||
<groupId>com.mchange</groupId>
|
||||
<artifactId>c3p0</artifactId>
|
||||
<version>0.9.5.2</version>
|
||||
</dependency>
|
||||
<!-- mysql-connector -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.29</version>
|
||||
<version>${slf4j-api.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- xxl-job-core -->
|
||||
|
@ -51,7 +34,6 @@
|
|||
<artifactId>xxl-job-core</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -33,6 +33,8 @@
|
|||
<property name="adminAddresses" value="${xxl.job.admin.addresses}" />
|
||||
<!-- 执行器日志路径[必填] -->
|
||||
<property name="logPath" value="${xxl.job.executor.logpath}" />
|
||||
<!-- 访问令牌,非空则进行匹配校验[选填] -->
|
||||
<property name="accessToken" value="${xxl.job.accessToken}" />
|
||||
</bean>
|
||||
|
||||
|
||||
|
|
|
@ -7,4 +7,7 @@ xxl.job.executor.ip=
|
|||
xxl.job.executor.port=9999
|
||||
|
||||
### xxl-job log path
|
||||
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler/
|
||||
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler/
|
||||
|
||||
### xxl-job, access token
|
||||
xxl.job.accessToken=
|
|
@ -8,6 +8,8 @@ import com.xxl.job.core.glue.GlueTypeEnum;
|
|||
import com.xxl.job.core.rpc.netcom.NetComClientProxy;
|
||||
|
||||
/**
|
||||
* executor-api client, test
|
||||
*
|
||||
* Created by xuxueli on 17/5/12.
|
||||
*/
|
||||
public class DemoJobHandlerTest {
|
||||
|
@ -31,7 +33,8 @@ public class DemoJobHandlerTest {
|
|||
triggerParam.setLogDateTim(System.currentTimeMillis());
|
||||
|
||||
// do remote trigger
|
||||
ExecutorBiz executorBiz = (ExecutorBiz) new NetComClientProxy(ExecutorBiz.class, "127.0.0.1:9999").getObject();
|
||||
String accessToken = null;
|
||||
ExecutorBiz executorBiz = (ExecutorBiz) new NetComClientProxy(ExecutorBiz.class, "127.0.0.1:9999", null).getObject();
|
||||
ReturnT<String> runResult = executorBiz.run(triggerParam);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>com.xuxueli</groupId>
|
||||
<artifactId>xxl-job</artifactId>
|
||||
<version>1.8.1-SNAPSHOT</version>
|
||||
<version>1.8.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>xxl-job-executor-springboot-example</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
@ -16,8 +16,6 @@
|
|||
<url>http://www.xuxueli.com/</url>
|
||||
|
||||
<properties>
|
||||
<spring-boot.version>1.3.8.RELEASE</spring-boot.version>
|
||||
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.7</java.version>
|
||||
|
@ -33,41 +31,44 @@
|
|||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- jetty -->
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
<version>${jetty-server.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-util</artifactId>
|
||||
<version>${jetty-server.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-http</artifactId>
|
||||
<version>${jetty-server.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-io</artifactId>
|
||||
<version>${jetty-server.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- spring-boot-starter-web (提供了对web的支持,包含了spring webmvc和tomcat等web开发的特性) -->
|
||||
<!-- spring-boot-starter-web (spring-webmvc + tomcat) -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- c3p0 -->
|
||||
<dependency>
|
||||
<groupId>com.mchange</groupId>
|
||||
<artifactId>c3p0</artifactId>
|
||||
<version>0.9.5.2</version>
|
||||
</dependency>
|
||||
<!-- mysql-connector -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.29</version>
|
||||
</dependency>
|
||||
|
||||
<!-- xxl-job-core -->
|
||||
<dependency>
|
||||
<groupId>com.xuxueli</groupId>
|
||||
|
|
|
@ -34,6 +34,8 @@ public class XxlJobConfig {
|
|||
@Value("${xxl.job.executor.logpath}")
|
||||
private String logpath;
|
||||
|
||||
@Value("${xxl.job.accessToken}")
|
||||
private String accessToken;
|
||||
|
||||
@Bean(initMethod = "start", destroyMethod = "destroy")
|
||||
public XxlJobExecutor xxlJobExecutor() {
|
||||
|
@ -44,6 +46,7 @@ public class XxlJobConfig {
|
|||
xxlJobExecutor.setAppName(appname);
|
||||
xxlJobExecutor.setAdminAddresses(addresses);
|
||||
xxlJobExecutor.setLogPath(logpath);
|
||||
xxlJobExecutor.setAccessToken(accessToken);
|
||||
return xxlJobExecutor;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,3 +15,6 @@ xxl.job.executor.port=9998
|
|||
|
||||
### xxl-job log path
|
||||
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler/
|
||||
|
||||
### xxl-job, access token
|
||||
xxl.job.accessToken=
|
||||
|
|
Loading…
Reference in New Issue