一、定时任务
为什么需要定时任务?
时间驱动处理场景: 整点发送优惠券,每天更新收益,每天刷新标签数据和人群数据。
批量处理数据: 按月批量统计报表数据,批量更新短信状态,实时性要求不高。
异步执行解耦: 活动状态刷新,数据同步,异步执行离线查询,与内部逻辑解耦。
- 实现方式:
- jdk方式:死循环、Timer定时器、JUC定时任务等
- springScheduling声明式定时任务:@EnableScheduling、@Scheduled
- 永远的经典:定时任务框架quartz
- 分布式定时任务:xxl-job(基于quartz)、elastic-Job(基于quartz)、Saturn(elastic-job的fork版本)、 MQ延时队列 等等。。。。。。。。。
- 各个解决方案的优缺点:
- jdk方式及springScheduling不支持高可用,不支持动态配置。
- quartz支持高可用(非常麻烦,需要10几张表),不支持动态配置。
- xxl-job支持高可用,动态配置以及任务的同一管理。
二、springScheduling 声明式
1、构建SpringBoot工程项目
1)创建一个Springboot工程,在它的程序入口加上 @EnableScheduling 注解,开启调度任务。
@EnableCustomConfig
@EnableCustomSwagger2
@EnableRyFeignClients
//@Import({WebConfig.class, MqttSenderConfig.class})
//@Import({MqttSenderConfig.class})
//@Import(RedissonConfig.class)
@EnableScheduling //开启调度任务
@SpringBootApplication
public class WisdomCtsApplication {
public static void main(String[] args) {
SpringApplication.run(WisdomCtsApplication.class, args);
System.out.println("(♥◠‿◠)ノ゙ 终端消息服务启动成功 ლ(´ڡ`ლ)゙ \n" +
" ██████ ██ ██ █████ █████ █████ ██████ ██████\n" +
" ██░░░░ ░██ ░██ ██░░░██ ██░░░██ ██░░░██ ██░░░░ ██░░░░ \n" +
"░░█████ ░██ ░██░██ ░░ ░██ ░░ ░███████░░█████ ░░█████ \n" +
" ░░░░░██░██ ░██░██ ██░██ ██░██░░░░ ░░░░░██ ░░░░░██\n" +
" ██████ ░░██████░░█████ ░░█████ ░░██████ ██████ ██████ \n" +
"░░░░░░ ░░░░░░ ░░░░░ ░░░░░ ░░░░░░ ░░░░░░ ░░░░░░ \n");
}
2、创建定时任务类
1)创建一个定时任务,(每月最后一天23点执行一次)清理数据库。
类添加 @Component 注解,方法添加 @Scheduled 注解。
@Component
public class ClearDataJob {
//注入service对象 方便调用
@Resource
private QueueServiceImpl queueService;
//0 0 23 L * ? 每月最后一天23点执行一次
@Scheduled(cron = "0 0 23 L * ?")
@Log(title = "定时任务",businessType = BusinessType.DELETE)
public void clearDataJob() {
clearData(queueService);
}
/**
* 清理数据
* @param queueService
*/
private static void clearData(QueueServiceImpl queueService) {
try {
queueService.deleteHomeNewsData();//调用service层的方法 删除队列数据库数据值
} catch (Exception e) {
throw new RuntimeException("清理数据失败,失败原因:" + e.getMessage());
}
}
}
2)cron表达式
- http://cron.qqe2.com 快捷生成cron表达式
- 常用的cron表达式
0 * * * * ? 每1分钟触发一次
0 0 * * * ? 每天每1小时触发一次
0 0 10 * * ? 每天10点触发一次
0 * 14 * * ? 在每天下午2点到下午2:59期间的每1分钟触发
0 30 9 1 * ? 每月1号上午9点半
0 15 10 15 * ? 每月15日上午10:15触发
*/5 * * * * ? 每隔5秒执行一次
0 */1 * * * ? 每隔1分钟执行一次
0 0 5-15 * * ? 每天5-15点整点触发
0 0/3 * * * ? 每三分钟触发一次
0 0-5 14 * * ? 在每天下午2点到下午2:05期间的每1分钟触发
0 0/5 14 * * ? 在每天下午2点到下午2:55期间的每5分钟触发
0 0/5 14,18 * * ? 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时
0 0 10,14,16 * * ? 每天上午10点,下午2点,4点
0 0 12 ? * WED 表示每个星期三中午12点
0 0 17 ? * TUES,THUR,SAT 每周二、四、六下午五点
0 10,44 14 ? 3 WED 每年三月的星期三的下午2:10和2:44触发
0 15 10 ? * MON-FRI 周一至周五的上午10:15触发
0 0 23 L * ? 每月最后一天23点执行一次
0 15 10 L * ? 每月最后一日的上午10:15触发
0 15 10 ? * 6L 每月的最后一个星期五上午10:15触发
0 15 10 * * ? 2005 2005年的每天上午10:15触发
0 15 10 ? * 6L 2002-2005 2002年至2005年的每月的最后一个星期五上午10:15触发
0 15 10 ? * 6#3 每月的第三个星期五上午10:15触发
三、xxl-job 分布式
XXL-Job是一个功能强大的分布式任务调度框架,集成了Spring Boot后能够发挥更大的优势。它提供了分布式任务调度、任务执行报告、任务调度中心、良好的扩展性、分布式集群部署、监控与报警等多种优势。此外,XXL-Job是开源免费的,可以在GitHub上获取源代码和详细文档。详细的文档和使用指南可以在XXL-Job的官方文档中找到。
1、下载XXL-Job
参考官方文档,我们需要下载一个xxl-job项目。
https://gitee.com/xuxueli0323/xxl-job
https://github.com/xuxueli/xxl-job
2、创建数据库并导入数据
从Gitee上下载下来的源码文件目录 /xxl-job/doc/db 下面有SQL文件 tables_xxl_job.sql ,然后再数据库创建数据库 xxl-job,我这里是和系统默认的一样也可以自己修改数据库名称;然后运行SQL文件导入下面表。
3、修改数据库连接配置
数据库连接配置在项目目录 xxl-job-admin/src/main/resources/application.properties ,如果需要配置发送邮箱则需要配置 spring.mail 下所有配置信息。
4、启动项目
在IDEA 启动项目后,访问:http://localhost:8080/xxl-job-admin,默认账号:admin,密码:123456
5、项目集成
5.1、导入依赖
<!-- xxl-job-core依赖 -->
<!-- https://mvnrepository.com/artifact/com.xuxueli/xxl-job-core -->
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>2.3.0</version>
</dependency>
5.2、配置 application.yml 信息
# Xxl-Job分布式定时任务调度中心
xxl:
job:
### 执行器通讯TOKEN [选填]:非空时启用;
accessToken:
admin:
### 调度中心部署根地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册;
addresses: http://127.0.0.1:8080/xxl-job-admin
executor:
### 执行器注册 [选填]:优先使用该配置作为注册地址,为空时使用内嵌服务 ”IP:PORT“ 作为注册地址。从而更灵活的支持容器类型执行器动态IP和动态映射端口问题。
address:
### 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册
appname: ddz-job-executor
### 执行器IP [选填]:默认为空表示自动获取IP,多网卡时可手动设置指定IP,该IP不会绑定Host仅作为通讯实用;地址信息用于 "执行器注册" 和 "调度中心请求并触发任务";
ip:
### 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口;
port: 9999
### 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;
logpath: /User/ddz/data/applogs/xxl-job/jobhandler
### 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能;
logretentiondays: 30
# 执行器通讯TOKEN [选填]:非空时启用;
accessToken:
5.3、XxlJobConfig 配置类
这个配置类在我们下载下来的项目中的目录下:xxl-job-executor-samples/xxl-job-executor-sample-springboot/src/main/java/com/xxl/job/executor/core/config/XxlJobConfig.java ,我们拷贝过来就能使用了
@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();
*/
}
5.4、添加执行器
进入 http://localhost:8080/xxl-job-admin,登录进去。
5.5、添加、启动任务
原文链接:https://blog.csdn.net/weixin_45626288/article/details/131561138