一、市面上常见的任务调度产品
针对分布式任务调度的需求,市场上出现了很多的产品:
其中XXL-job 是我们经常使用的任务调度平台,XXL这三个英文字母.是以作者名许雪里命名的。
可以前往 Gitee 地址进行下载使用
https://gitee.com/xuxueli0323/xxl-job.git
二、XXL-JOB的基本使用
在Gitee地址下载完XXL-job 的项目后,项目的结构如下:
2.1、启动xxl-job-admin服务
首先启动xxl-job-admin,并在配置文件中修改对应的端口号以及虚拟路径,配置文件中部分默认的参数如下:
xxl-job-admin服务是XXL-JOB的web页面端,所以启动完xxl-job-admin服务后,可以访问:
http://localhost:8080/xxl-job-admin/
账号:admin
密码:123456
2.2、登陆xxl-job的web页面
2.2.1、执行器管理
执行器管理页面中有一个默认的执行器xxl-job-executor-sample,下面来介绍如何编辑执行器。
AppName是执行器的唯一标示,所以不能重复。
名称可以自己随便写,但是最好见名知意,帮助我们快速的了解这个执行器的作用。
注册方式是调度中心获取执行器地址的方式 ,一般选自动注册。
自动注册和手动录入的区别:
总结:
2.2.2、任务管理
任务管理页面是用来编辑任务执行的,下面来介绍如何编辑任务管理。
执行器:每一个任务要对应一个执行器,所以要选择一个执行器,可供选择的执行器,就是在2.2.1中编辑好的执行器。
任务描述:此次任务的作用是什么。
负责人:这个任务的负责人是谁。
调度类型:CRON、无、固定速度
CRON:是通过CRON表达式来控制任务调用的时间,这个在后面会做一个详细的介绍。
无:不调用
固定速度:以固定的时间进行调用,例如每隔5秒进行调用,这个通过CRON表达式也能实现,所以不推荐使用固定速度。
运行模式:运行模式主要分为BEAN和GLUE。BEAN是通过java代码进行运行,GLUE是通过脚本的方式进行运行(有些银行的就是采用这种方式)
JobHander:运行模式采用BEAN,右边就会出现JobHander,JobHander中的值可以任意写,但是要和代码中的值保持一致,代码中通过@XxlJob注解和JobHander中的值相对应。
路由策略:
当执行器集群部署时,提供丰富的路由策略
阻塞处理策略:调度过于密集执行器来不及处理时的处理策略
2.3、启动xxl-job-executor-sample-springboot
xxl-job-executor-sample-springboot 中配置文件里面需要注意的有:
xxl.job.admin.addresses:对应2.1中web页面的IP地址、端口号、虚拟路径等
xxl.job.executor.appname:对应2.2.1中执行器的AppName
xxl.job.executor.port:对应执行器的端口号(和server.port中的端口号不一样)。
在 xxl-job-executor-sample-springboot中可以看见XxlJobConfig用来读取配置文件中的值
package com.xxl.job.executor.core.config;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* xxl-job config
*
* @author xuxueli 2017-04-28
*/
@Configuration
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;
@Bean
public 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();
*/
}
在SampleXxlJob类中,用来执行任务。
@Component
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.");
for (int i = 0; i < 5; i++) {
System.out.println("执行了第"+i+"次");
//XxlJobHelper.log("beat at:" + i);
TimeUnit.SECONDS.sleep(2);
}
// default success
}
}
SampleXxlJob中@XxlJob的值要和2.2.2任务管理中JobHander的值保持一致。再启动xxl-job-executor-sample-springboot服务。
启动了xxl-job-executor-sample-springboot服务以及xxl-job-admin服务后,在任务管理页面点击执行一次,即可发起调用。
发现调用成功
三、 Corn表达式
2.2.2中可以通过Corn表达式来控制任务调度的时间,以下是Corn表达式中符号的含义
以下面这个 Corn表达式为例
6-21:在时域,表示从早上6点到晚上9点执行。(“-”:指定一个范围,可以看上表)
0/5:在分域,表示每5分钟执行一次。(“/”:表示递增,可以看上表)
0:在秒域,表示第0秒执行。
连起来就是:早上6点到晚上9点这个时间段内,每隔5分钟执行一次。
例如:06:05:00、06:10:00、06:15:00、06:20:00、06:25:00,一直执行到晚上9点55分。
另外:我后面在天域和月域中设置了通配符“*”,表示每月的每天执行。所以就是永远在执行,所以在年域和周域用“?”,“不指定”也不影响。