【Java开发-Nutz】Nutz框架集成Quartz定时任务解决方案

Nutz框架集成Quartz定时任务解决方案

Nutz本身是个很不错的国产框架,轻量级、上手快,感兴趣的小伙伴可以去参考官网文档学习,使用,Nutz栏目主要是用于日常工作积累、备忘和分享。

功能需求

  • 需求一:通过数据库任务信息能够动态控制任务的启动和停止
  • 需求二:定时任务支持Cron和时间间隔触发器方式
  • 需求三:能够实时监控任务状态

实现与设计思路

1.首先通过程序我们需要实现动态上的任务启停功能,这样我们就可以通过读取数据库的任务信息配置,来做到任务的启动和停止。
注意:这里我是使用了一个内置任务来监控任务信息表,这样我只用更新任务信息表,不在操作的时候考虑任务的启停,如果对实时性要求非常高这里建议不要使用我这种方式,在更新数据库前先动态启动任务,再去更新数据库的任务信息,保证系统任务和数据库信息同步,不过这样做,需要在系统启动和停止时,考虑到任务状态,这样即使重启系统,也能保证任务恢复到停止前的状态。
2.其次任务的启动方式满足cron表达式和时间间隔,就需要我们准备这两种触发器
3.监控任务状态,需要我们对所有任务进行动态监听,可将任务执行结果进行日志打印或记录到数据库和本地文件中,方便查看。

引入工具包

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.wuxx</groupId>
  <artifactId>nutz-quartz</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>nutz-quartz Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <properties>
    <nutz.version>1.r.68.v20190220</nutz.version>
    <nutz.quartz.version>1.r.70-SNAPSHOT</nutz.quartz.version>
    <mysql.conn.version>8.0.33</mysql.conn.version>
    <servlet-api.version>3.1.0</servlet-api.version>
    <druid.version>1.2.23</druid.version>
    <log4j.version>2.20.0</log4j.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.nutz</groupId>
      <artifactId>nutz</artifactId>
      <version>${nutz.version}</version>
    </dependency>

    <dependency>
      <groupId>org.nutz</groupId>
      <artifactId>nutz-integration-quartz</artifactId>
      <version>${nutz.quartz.version}</version>
    </dependency>

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>${mysql.conn.version}</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>${servlet-api.version}</version>
      <scope>provided</scope>
    </dependency>
    <!-- Druid连接池 -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>${druid.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>${log4j.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-slf4j-impl</artifactId>
      <version>${log4j.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-1.2-api</artifactId>
      <version>${log4j.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-web</artifactId>
      <version>${log4j.version}</version>
    </dependency>
  </dependencies>
  <build>
    <finalName>nutz-quartz</finalName>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
          <compilerArgs>
            <arg>-parameters</arg>
          </compilerArgs>
          <useIncrementalCompilation>false</useIncrementalCompilation>
        </configuration>
      </plugin>
    </plugins>
  </build>

  <repositories>
    <repository>
      <id>nutz</id>
      <url>http://jfrog.nutz.cn/artifactory/libs-release</url>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </repository>
    <repository>
      <id>nutz-snapshots</id>
      <url>http://jfrog.nutz.cn/artifactory/snapshots</url>
      <snapshots>
        <enabled>true</enabled>
        <updatePolicy>always</updatePolicy>
      </snapshots>
      <releases>
        <enabled>false</enabled>
      </releases>
    </repository>
  </repositories>
</project>

数据库设计

表设计

在这里插入图片描述

创建脚本

/*
 Navicat Premium Data Transfer

 Source Server         : localhost
 Source Server Type    : MySQL
 Source Server Version : 80402
 Source Host           : localhost:3306
 Source Schema         : test

 Target Server Type    : MySQL
 Target Server Version : 80402
 File Encoding         : 65001

 Date: 16/12/2024 15:17:19
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for s_task_info
-- ----------------------------
DROP TABLE IF EXISTS `s_task_info`;
CREATE TABLE `s_task_info`  (
  `TASK_ID` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '主键',
  `TASK_CH_NAME` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '任务名称',
  `TASK_EN_NAME` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '任务英文名称',
  `TASK_GROUP` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '任务分组',
  `TASK_DESCRIPTION` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '任务描述',
  `TASK_CRON` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '任务策略CRON',
  `TASK_CLASS` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '任务加载类',
  `TASK_TYPE` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '任务类型',
  `TASK_EXECUTION_TIME` datetime(0) NULL DEFAULT NULL COMMENT '任务执行时间',
  `STATUS` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '状态(运行中、暂停、停止)',
  `CREATE_TIME` timestamp(6) NOT NULL COMMENT '创建时间',
  `UPDATE_TIME` timestamp(6) NULL DEFAULT NULL COMMENT '更新时间',
  `DEL_FLAG` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '静态任务标记(0否1是)',
  `TASK_INTERVAL_UNIT` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '间隔时间类型,支持毫秒、秒、分钟、小时',
  `TASK_INTERVAL` int(0) NULL DEFAULT NULL COMMENT '间隔时长',
  `TASK_REPEAT` int(0) NULL DEFAULT NULL COMMENT '重复次数',
  PRIMARY KEY (`TASK_ID`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '任务信息表' ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of s_task_info
-- ----------------------------
INSERT INTO `s_task_info` VALUES ('69f59841d659438281fc2b2ff6474683', '测试任务', 'testJob', 'Job1', '测试任务', '0 0/1 * * * ? ', 'com.wuxx.task.TestJob', 'CRON', '2024-12-16 15:14:09', '1', '2024-12-16 15:14:09.000000', '2024-12-16 15:14:09.000000', '0', 'INTERVAL_MINUTE', 1, 0);

SET FOREIGN_KEY_CHECKS = 1;

项目功能介绍

项目源码

nutz-quartz工程源码地址:gitCode
在这里插入图片描述

两种触发器的使用

通过任务类型配置,使用不同的触发器来启动任务,所以我们想使用不同的触发器,只需要设置不同的类型,任务类型包含:任务类型包含(taskType):
* CRON(“标准CRON支持”),
* INTERVAL_MILLISECOND(“固定间隔毫秒”),
* INTERVAL_SECOND(“固定间隔秒”),
* INTERVAL_MINUTE(“固定间隔分钟”),
* INTERVAL_HOUR(“固定间隔小时”)
在这里插入图片描述

taskType字段为以“INTERVAL_”类型开头时,需要设置taskIntervalUnit的时间间隔单位,还需要设置时间间隔(taskInterval),同时还能设置重复次数(taskRepeat,如果taskRepeat是0,则表示该任务无限重复)。

任务监听

/**
 * created by wuxx on 2024/12/16.
 * 监听器,用于监控任务的执行情况
 */
public class QuartzListener implements JobListener {
    private static Logger log = LogManager.getLogger(QuartzListener.class);

    @Override
    public String getName() {
        String name = this.getClass().getSimpleName();
        log.debug("监听器的名称为: "+name);
        return System.currentTimeMillis() + "QuartzListener";
    }

    @Override
    public void jobToBeExecuted(JobExecutionContext jobExecutionContext) {
        String name = jobExecutionContext.getJobDetail().getKey().getName(); //获取Job的name
        log.debug("被监听的job的name是:"+name+"   Scheduler在JobDetail将要被执行时调用的方法");
    }

    @Override
    public void jobExecutionVetoed(JobExecutionContext jobExecutionContext) {
        String name = jobExecutionContext.getJobDetail().getKey().getName(); //获取Job的name
        log.debug("Scheduler在JobDetail即将执行,但又被TriggerListerner否决时会调用的方法");
    }

    @Override
    public void jobWasExecuted(JobExecutionContext jobExecutionContext, JobExecutionException e) {
        String name = jobExecutionContext.getJobDetail().getKey().getName(); //获取Job的name
        log.debug("Scheduler是在JobDetail被执行之后调用这个方法的");
    }
}

可以根据实际的业务逻辑需求,在相应的方法中添加自己的业务逻辑,完成任务监听功能

任务分组

将任务分组配置,可以部署多个实例,可以保证每个实例上运行的任务不会重复

#任务分组,依据数据库taskGroup,多个任务组使用英文逗号间隔
quartz.task-group Job1,Job2,job3

运行结果

在这里插入图片描述

结尾

此方案相对来说不是很复杂,只是满足的最基础的业务功能需求,如果有更复杂的要求,也能在此基础上进行功能优化和增加,如此记录一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

筱星_wu

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值