XXL-JOB是一个轻量级分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用

xxl-job的特性

1、简单:支持通过Web页面对任务进行CRUD操作,操作简单,一分钟上手;
2、动态:支持动态修改任务状态、启动/停止任务,以及终止运行中任务,即时生效;
3、调度中心HA(中心式):调度采用中心式设计,“调度中心”自研调度组件并支持集群部署,可保证调度中心HA;
4、执行器HA(分布式):任务分布式执行,任务"执行器"支持集群部署,可保证任务执行HA;
5、注册中心: 执行器会周期性自动注册任务, 调度中心将会自动发现注册的任务并触发执行。同时,也支持手动录入执行器地址;
6、弹性扩容缩容:一旦有新执行器机器上线或者下线,下次调度时将会重新分配任务;
7、路由策略:执行器集群部署时提供丰富的路由策略,包括:第一个、最后一个、轮询、随机、一致性HASH、最不经常使用、最近最久未使用、故障转移、忙碌转移等;
8、故障转移:任务路由策略选择"故障转移"情况下,如果执行器集群中某一台机器故障,将会自动Failover切换到一台正常的执行器发送调度请求。
9、阻塞处理策略:调度过于密集执行器来不及处理时的处理策略,策略包括:单机串行(默认)、丢弃后续调度、覆盖之前调度;
10、任务超时控制:支持自定义任务超时时间,任务运行超时将会主动中断任务;
11、任务失败重试:支持自定义任务失败重试次数,当任务失败时将会按照预设的失败重试次数主动进行重试;其中分片任务支持分片粒度的失败重试;
12、任务失败告警;默认提供邮件方式失败告警,同时预留扩展接口,可方便的扩展短信、钉钉等告警方式;
13、分片广播任务:执行器集群部署时,任务路由策略选择"分片广播"情况下,一次任务调度将会广播触发集群中所有执行器执行一次任务,可根据分片参数开发分片任务;
14、动态分片:分片广播任务以执行器为维度进行分片,支持动态扩容执行器集群从而动态增加分片数量,协同进行业务处理;在进行大数据量业务操作时可显著提升任务处理能力和速度。
15、事件触发:除了"Cron方式"和"任务依赖方式"触发任务执行之外,支持基于事件的触发任务方式。调度中心提供触发任务单次执行的API服务,可根据业务事件灵活触发。
16、任务进度监控:支持实时监控任务进度;
17、Rolling实时日志:支持在线查看调度结果,并且支持以Rolling方式实时查看执行器输出的完整的执行日志;
18、GLUE:提供Web IDE,支持在线开发任务逻辑代码,动态发布,实时编译生效,省略部署上线的过程。支持30个版本的历史版本回溯。
19、脚本任务:支持以GLUE模式开发和运行脚本任务,包括Shell、Python、NodeJS、PHP、PowerShell等类型脚本;
20、命令行任务:原生提供通用命令行任务Handler(Bean任务,“CommandJobHandler”);业务方只需要提供命令行即可;
21、任务依赖:支持配置子任务依赖,当父任务执行结束且执行成功后将会主动触发一次子任务的执行, 多个子任务用逗号分隔;
22、一致性:“调度中心”通过DB锁保证集群分布式调度的一致性, 一次任务调度只会触发一次执行;
23、自定义任务参数:支持在线配置调度任务入参,即时生效;
24、调度线程池:调度系统多线程触发调度运行,确保调度精确执行,不被堵塞;
25、数据加密:调度中心和执行器之间的通讯进行数据加密,提升调度信息安全性;
26、邮件报警:任务失败时支持邮件报警,支持配置多邮件地址群发报警邮件;
27、推送maven中央仓库: 将会把最新稳定版推送到maven中央仓库, 方便用户接入和使用;
28、运行报表:支持实时查看运行数据,如任务数量、调度次数、执行器数量等;以及调度报表,如调度日期分布图,调度成功分布图等;
29、全异步:任务调度流程全异步化设计实现,如异步调度、异步运行、异步回调等,有效对密集调度进行流量削峰,理论上支持任意时长任务的运行;
30、跨平台:原生提供通用HTTP任务Handler(Bean任务,“HttpJobHandler”);业务方只需要提供HTTP链接即可,不限制语言、平台;
31、国际化:调度中心支持国际化设置,提供中文、英文两种可选语言,默认为中文;
32、容器化:提供官方docker镜像,并实时更新推送dockerhub,进一步实现产品开箱即用;
33、线程池隔离:调度线程池进行隔离拆分,慢任务自动降级进入"Slow"线程池,避免耗尽调度线程,提高系统稳定性;
34、用户管理:支持在线管理系统用户,存在管理员、普通用户两种角色;
35、权限控制:执行器维度进行权限控制,管理员拥有全量权限,普通用户需要分配执行器权限后才允许相关操作;

docker部署xxl-job(文件映射)

下载xxl-job-admin的数据库脚本

wget https://raw.githubusercontent.com/xuxueli/xxl-job/2.0.2/doc/db/tables_xxl_job.sql

下载application.properties

wget https://raw.githubusercontent.com/xuxueli/xxl-job/2.0.2/xxl-job-admin/src/main/resources/application.properties

拉取镜像

docker pull xuxueli/xxl-job-admin:2.0.2

启动容器

docker run -d --name=cg_xxl-job-admin -v $PWD/application.properties:/application.properties  --net host -e PARAMS='--spring.config.location=/application.properties' xuxueli/xxl-job-admin:2.0.2

application.properties

### web
# 端口号
server.port=8080
# 根目录, 启动后的访问地址为: http://ip:[server.port]/[server.context-path]
server.context-path=/xxl-job-admin### resources
# 静态资源配置, 不需要修改
spring.mvc.static-path-pattern=/static/**
spring.resources.static-locations=classpath:/static/### freemarker
# freemarker模版配置, 不需要修改
spring.freemarker.templateLoaderPath=classpath:/templates/
spring.freemarker.suffix=.ftl
spring.freemarker.charset=UTF-8
spring.freemarker.request-context-attribute=request
spring.freemarker.settings.number_format=0.############# mybatis
# mybatis配置, 不需要修改
mybatis.mapper-locations=classpath:/mybatis-mapper/*Mapper.xml### xxl-job, datasource
# 数据库配置, 根据实际情况修改
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_job?Unicode=true&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=root_pwd
spring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.datasource.type=org.apache.tomcat.jdbc.pool.DataSource
spring.datasource.tomcat.max-wait=10000
spring.datasource.tomcat.max-active=30
spring.datasource.tomcat.test-on-borrow=true
spring.datasource.tomcat.validation-query=SELECT 1
spring.datasource.tomcat.validation-interval=30000### xxl-job email
# 邮件发送配置
spring.mail.host=smtp.qq.com
spring.mail.port=25
spring.mail.username=xxx@qq.com
spring.mail.password=xxx
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory### xxl-job, access token
# 和客户端通信的token, 非空的时候启用, 如果不为空, 则客户端也需要填相同的token
xxl.job.accessToken=### xxl-job, i18n (default empty as chinese, "en" as english)
# 国际化, 不需要改
xxl.job.i18n=

docker部署xxl-job(建立容器时指定参数,无法随时更改)

拉取镜像

docker pull xuxueli/xxl-job-admin:2.3.0

启动容器

docker run -e PARAMS="--spring.datasource.url=jdbc:mysql://192.168.220.130:3307/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=UTC --spring.datasource.username=root --spring.datasource.password=cgroot" -p 8090:8080  -v /root/xxjob/xxjobData:/data/applogs --name=cg_xxl-job-admin -d xuxueli/xxl-job-admin:2.3.0

访问地址:http://192.168.220.130:9999/xxl-job-admin/jobinfo
账号密码默认为:admin,123456

新增任务

默认执行器

springboot 集成xxl-job

导入依赖

     <dependency><groupId>com.xuxueli</groupId><artifactId>xxl-job</artifactId><version>2.3.0</version></dependency>

修改配置

api: initListen:###开启配置xxl: true
xxl:job:admin:### xxl-job admin address list, such as "http://address" or "http://address01,http://address02"addresses: http://xxx.xx.xx.xx:8090/xxl-job-admin/userName: adminpassword: 123456### xxl-job, access tokenaccessToken:executor:### xxl-job executor appnameappname: xxl-job-executor-sample### xxl-job executor registry-address: default use address to registry , otherwise use ip:port if address is nulladdress:### xxl-job executor server-infoip:### 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口;port: 9092### 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径logpath: logs/xxl-job/jobhandler### xxl-job executor log-retention-dayslogretentiondays: 7

其中的address与ip不填会自动获取地址适合新手尝试使用,如使用nginx转发需要自行配置地址

配置类

@Configuration
@ConditionalOnProperty(prefix = "api", name = "initListen.xxl")
public class XxlJobConfig {private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);@Value("${xxl.job.admin.addresses}")private String adminAddresses;@Value("${xxl.job.accessToken}")private String accessToken;@Value("${xxl.job.executor.appname}")private String appname;@Value("${xxl.job.executor.address}")private String address;@Value("${xxl.job.executor.ip}")private String ip;@Value("${xxl.job.executor.port}")private int port;@Value("${xxl.job.executor.logpath}")private String logPath;@Value("${xxl.job.executor.logretentiondays}")private int logRetentionDays;@Beanpublic XxlJobSpringExecutor xxlJobExecutor() {logger.info(">>>>>>>>>>> xxl-job config init.");XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();xxlJobSpringExecutor.setAdminAddresses(adminAddresses);xxlJobSpringExecutor.setAppname(appname);xxlJobSpringExecutor.setAddress(address);xxlJobSpringExecutor.setIp(ip);xxlJobSpringExecutor.setPort(port);xxlJobSpringExecutor.setAccessToken(accessToken);xxlJobSpringExecutor.setLogPath(logPath);xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);return xxlJobSpringExecutor;}/*** 针对多网卡、容器内部署等情况,可借助 "spring-cloud-commons" 提供的 "InetUtils" 组件灵活定制注册IP;**      1、引入依赖:*          <dependency>*             <groupId>org.springframework.cloud</groupId>*             <artifactId>spring-cloud-commons</artifactId>*             <version>${version}</version>*         </dependency>**      2、配置文件,或者容器启动变量*          spring.cloud.inetutils.preferred-networks: 'xxx.xxx.xxx.'**      3、获取IP*          String ip_ = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();*/}

任务类


/*** XxlJob开发示例(Bean模式)* <p>* 开发步骤:* 1、任务开发:在Spring Bean实例中,开发Job方法;* 2、注解配置:为Job方法添加注解 "@XxlJob(value="自定义jobhandler名称", init = "JobHandler初始化方法", destroy = "JobHandler销毁方法")",注解value值对应的是调度中心新建任务的JobHandler属性的值。* 3、执行日志:需要通过 "XxlJobHelper.log" 打印执行日志;* 4、任务结果:默认任务结果为 "成功" 状态,不需要主动设置;如有诉求,比如设置任务结果为失败,可以通过 "XxlJobHelper.handleFail/handleSuccess" 自主设置任务结果;** @author xuxueli 2019-12-11 21:52:51*/
@Component
@Slf4j
public class SampleXxlJob {private static Logger logger = LoggerFactory.getLogger(SampleXxlJob.class);/*** 1、简单任务示例(Bean模式)*/@XxlJob("demoJobHandler")public void demoJobHandler() throws Exception {XxlJobHelper.log("XXL-JOB, Hello World.");log.info("XXL-JOB, Hello World.");for (int i = 0; i < 5; i++) {XxlJobHelper.log("beat at:" + i);TimeUnit.SECONDS.sleep(1);}// default success}/*** 2、分片广播任务*/@XxlJob("shardingJobHandler")public void shardingJobHandler() throws Exception {// 分片参数int shardIndex = XxlJobHelper.getShardIndex();int shardTotal = XxlJobHelper.getShardTotal();log.info("分片参数:当前分片序号 = {}, 总分片数 = {}", shardIndex, shardTotal);XxlJobHelper.log("分片参数:当前分片序号 = {}, 总分片数 = {}", shardIndex, shardTotal);// 业务逻辑for (int i = 0; i < shardTotal; i++) {if (i == shardIndex) {XxlJobHelper.log("第 {} 片, 命中分片开始处理", i);} else {XxlJobHelper.log("第 {} 片, 忽略", i);}}}/*** 3、命令行任务*/@XxlJob("commandJobHandler")public void commandJobHandler() throws Exception {String command = XxlJobHelper.getJobParam();log.info("命令任务-command {}", command);int exitValue = -1;BufferedReader bufferedReader = null;try {// command processProcessBuilder processBuilder = new ProcessBuilder();processBuilder.command(command);processBuilder.redirectErrorStream(true);Process process = processBuilder.start();//Process process = Runtime.getRuntime().exec(command);BufferedInputStream bufferedInputStream = new BufferedInputStream(process.getInputStream());bufferedReader = new BufferedReader(new InputStreamReader(bufferedInputStream));// command logString line;while ((line = bufferedReader.readLine()) != null) {XxlJobHelper.log(line);}// command exitprocess.waitFor();exitValue = process.exitValue();} catch (Exception e) {XxlJobHelper.log(e);} finally {if (bufferedReader != null) {bufferedReader.close();}}if (exitValue == 0) {// default success} else {XxlJobHelper.handleFail("command exit value(" + exitValue + ") is failed");}}/*** 4、跨平台Http任务* 参数示例:* "url: http://www.baidu.com\n" +* "method: get\n" +* "data: content\n";*/@XxlJob("httpJobHandler")public void httpJobHandler() throws Exception {// param parseString param = XxlJobHelper.getJobParam();log.info("http任务-param {}", param);if (param == null || param.trim().length() == 0) {XxlJobHelper.log("param[" + param + "] invalid.");XxlJobHelper.handleFail();return;}String[] httpParams = param.split("\n");String url = null;String method = null;String data = null;for (String httpParam : httpParams) {if (httpParam.startsWith("url:")) {url = httpParam.substring(httpParam.indexOf("url:") + 4).trim();}if (httpParam.startsWith("method:")) {method = httpParam.substring(httpParam.indexOf("method:") + 7).trim().toUpperCase();}if (httpParam.startsWith("data:")) {data = httpParam.substring(httpParam.indexOf("data:") + 5).trim();data= StringUtils.replace(data, "[now]", DateUtil.now());}}// param validif (url == null || url.trim().length() == 0) {XxlJobHelper.log("url[" + url + "] invalid.");XxlJobHelper.handleFail();return;}if (method == null || !Arrays.asList("GET", "POST").contains(method)) {XxlJobHelper.log("method[" + method + "] invalid.");XxlJobHelper.handleFail();return;}boolean isPostMethod = method.equals("POST");// requestHttpURLConnection connection = null;BufferedReader bufferedReader = null;try {// connectionURL realUrl = new URL(url);connection = (HttpURLConnection) realUrl.openConnection();// connection settingconnection.setRequestMethod(method);connection.setDoOutput(isPostMethod);connection.setDoInput(true);connection.setUseCaches(false);connection.setReadTimeout(5 * 1000);connection.setConnectTimeout(3 * 1000);connection.setRequestProperty("connection", "Keep-Alive");connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");connection.setRequestProperty("Accept-Charset", "application/json;charset=UTF-8");// do connectionconnection.connect();// dataif (isPostMethod && data != null && data.trim().length() > 0) {DataOutputStream dataOutputStream = new DataOutputStream(connection.getOutputStream());dataOutputStream.write(data.getBytes("UTF-8"));dataOutputStream.flush();dataOutputStream.close();}// valid StatusCodeint statusCode = connection.getResponseCode();if (statusCode != 200) {throw new RuntimeException("Http Request StatusCode(" + statusCode + ") Invalid.");}// resultbufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));StringBuilder result = new StringBuilder();String line;while ((line = bufferedReader.readLine()) != null) {result.append(line);}String responseMsg = result.toString();XxlJobHelper.log(responseMsg);return;} catch (Exception e) {XxlJobHelper.log(e);XxlJobHelper.handleFail();return;} finally {try {if (bufferedReader != null) {bufferedReader.close();}if (connection != null) {connection.disconnect();}} catch (Exception e2) {XxlJobHelper.log(e2);}}}/*** 5、生命周期任务示例:任务初始化与销毁时,支持自定义相关逻辑;*/@XxlJob(value = "demoJobHandler2", init = "init", destroy = "destroy")public void demoJobHandler2() throws Exception {XxlJobHelper.log("XXL-JOB, Hello World.");}public void init() {logger.info("init");}public void destroy() {logger.info("destory");}
}

xxl-job——docker相关推荐

  1. docker部署xxl-job 通用反射执行器

    原因 最近在公司写一些job,公司使用的是spring boot提供的注解形式实现的. 这样在自测的时候很麻烦,而且测试提测的时候需要修改cron表达式->提交git->jenkins打包 ...

  2. docker安装xxl-job-admin步骤

    下载镜像 docker pull xuxueli/xxl-job-admin:2.2.0 查看镜像 docker images 初始化数据库 Mysql脚本:  https://github.com/ ...

  3. docker 自制XXL_JOB镜像启动

    XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速.学习简单.轻量级.易扩展.现已开放源代码并接入多家公司线上产品线,开箱即用. 开发参考文档:https://www.xuxueli.c ...

  4. XXL-JOB 执行器用docker的方式来运行,执行的IP为虚拟IP解决方案

    问题症状 微服务均以docker方式运行,注册到xxljob的IP均为自动获取,导致为docker容器的虚拟IP 172.x.x.x,怎么办? Nacos配置 xxl.job.executor.ip ...

  5. SpringBoot整合XXLJob+Docker部署

    1.概述 XXL-JOB是一个轻量级分布式任务调度平台,其核心设计目标是开发迅速.学习简单.轻量级.易扩展.现已开放源代码并接入多家公司线上产品线,开箱即用.xxl三个字母是其开发者许雪里名字的缩写. ...

  6. docker 和 k8s 安装xxljob

    docker安装 准备资料: 到dockerhub拉取最新镜像:https://hub.docker.com/r/xuxueli/xxl-job-admin/tags 到github下载xxl_job ...

  7. /var/lib/docker/overlay2/xxxxx no such file or directory docker文件删除引发的问题

    记一次误删引发的服务雪崩 K8s node节点磁盘报警,报警后我找到服务中占用磁盘最多的地方,在overlay2目录下,对下面的文件进行了删除   删除后,有状态服务先出现了问题,服务无法启动.停止. ...

  8. 本地打包Docker镜像上传至阿里云远程仓库(一站式脚本)

    打包镜像上传至远程仓库: 1. 本地项目为 mytest-project 2. 仓库为阿里云镜像仓库 registry.cn-beijing.aliyuncs.com/test/mytest-proj ...

  9. docker报错:driver failed programming external connectivity on endpoint, iptables:No chain by that name

    docker 报错: Error response from daemon: Cannot restart container hello: driver failed programming ext ...

  10. Docker容器的备份与恢复,Docker镜像的备份与恢复

    1. 备份容器 首先,为了备份Docker中的容器,我们会想看看我们想要备份的容器列表.要达成该目的,我们需要在我们运行着Docker引擎,并已创建了容器的Linux机器中运行 docker ps 命 ...

最新文章

  1. sql2000 转sql2008
  2. C#语法浮点型字面量
  3. 马斯克学什么计算机语言,马斯克头脑风暴——对计算机如醉如痴
  4. Kotlin 中的 run、let、with、apply、also、takeIf、takeUnless 语法糖使用和原理分析
  5. #串口通信超时处理_【学院推荐】划重点!LabVIEW中串口参数需注意的几点
  6. centos7.9使用rpm安装Jenkins_亲测成功---持续集成部署Jenkins工作笔记0022
  7. install texlive-full on ubuntu
  8. jsp+mysql汽车维修管理系统的设计与开发_基于JSP+MySQl的计算机学院设备报修管理系统.doc...
  9. truffle和remix区别
  10. CoolFire系列讲座 第4讲:字典档的维护及更新
  11. r语言平均值显著性检验_R语言与显著性检验学习笔记
  12. 安装CAD显示计算机丢失SETUPUI,彻底解决CAD2012不能安装问题.docx
  13. Latex科技论文写作
  14. OPTA 7模式测试说明
  15. Junit 的 @RunWith():Runner,即Junit的运行器
  16. Angr-CTF学习笔记11-13
  17. 解决home end pgup pgdn没有独立,需要键盘映射的问题
  18. gdb+openocd+stlink调试MCU
  19. cad怎么将图层后置_CAD图层遮挡,如何将CAD图形进行前置或者后置?
  20. Mysql中如何根据.frm和.idb文件恢复表结构

热门文章

  1. 开源:安卓手机app控制arduino,通过esp8266-01
  2. D3D9学习笔记之基础几何体的深入应用(一)
  3. requirement生成和使用
  4. linux ptp时钟同步
  5. vs2017设置背景图片
  6. Security登录页面显示:Bad credentials 或者 BCryptPasswordEncoder : Encoded password does not look like BCrypt
  7. 学java好还是学挖机好_现在开挖掘机还能月入上万吗,为何年轻人还是热衷于学挖掘机?...
  8. 如何使用云桌面系统提高涉密网络安全性与方便性
  9. 事物(Transaction)
  10. 毕业设计 基于单片机的万能红外遥控器 - 物联网 嵌入式