首页 > 其他分享 >Quartz集群增强版_00.How to use?(如何使用)

Quartz集群增强版_00.How to use?(如何使用)

时间:2024-11-11 19:58:32浏览次数:1  
标签:00 Quartz 配置 spring 增强版 quartz import org 执行

Quartz集群增强版_00.How to use?(如何使用)

转载请著名出处 https://www.cnblogs.com/funnyzpc/p/18540378

开源地址 https://github.com/funnyzpc/quartz

表的基本结构

    总的来说任务的配置及开发基本遵从上图的表的基本关系,除 app 以及 node 之外均需要手动手动配置,appnode 在执行端启动的时候会自动生成对应 app 以及 node 的数据 ~

后管配置

先看一下后管的基本页面~
因为 appnode 是一对多的关系,这里就放到一个page下:

  • 这里需要说明的是appnode一般无需新增,如果特殊情况下请参照下图:

app新增

node新增

因为node必须关联已有的app才可新增,新增入口在app列表

另外,需要说明的是:

  • 如果执行端获取不到宿主机IP以及主机名称会随机生成一个同名的 主机IP以及主机名称,此时在管理端手动新增就毫无意义了

    删除

  • 删除应用必须先删除应用关联的节点(node),节点被删除则节点对应的执行端无法执行其任务,删除应用也是

  • 删除应用或节点不会变更任务及执行项的状态,也不会删除任务及执行项,没有节点的执行项不会执行也会定期被清理

    启用/关闭

启用与关闭只操作节点或应用,关闭节点则节点下的所有任务均不会执行,关闭应用则应用关联的所有结点都不会执行任务,同时这个操作也不会变更任务或执行项~

再看看节点任务及执行配置:

任务/执行配置是管理端主要任务,执行配置使用关联任务配置(PID)关联相应的任务(job),执行项(execute)是不可独立存在的!

新增任务配置

  • 应用名称/调度名称就是自动或手动配置的应用信息
    任务状态在配置时仅可有 初始化(INIT)/正常执行(EXECUTING) 这两种状态,如果只是配置不想立即执行就选 初始化(INIT)

    新增执行配置-CRON时间任务

  • 任务类型仅可为简单任务(SIMPLE)或表达式(CRON)的时间项的任务,两种类型的执行配置(execute)填写的字段会有区别
    CRON任务CRON表达式是必填项,时区现阶段默认是Asia/Shanghai ,后续会改成从系统获取默认
    开始时间一般不填则默认就是-1,新增提交后是按当前时间补充
    结束时间也是非必填的,结束时间默认也是-1,结束时间如果是-1则在执行完最后一次任务之后会补充为最后一次执行时间

    新增执行配置-SIMPLE时间任务

  • 图中圈出的为必填项,需要说明的是:如果执行结束时间执行次数均设置,具体任务执行时会依限制范围最小的为实际执行,比如设置的结束时间较长但是执行次数只有几次,那最终大概率只会以执行次数为限制执行

    另外,对于执行配置,当执行完成后,对应的执行配置仅可删除不可 修改或启停,已经完成的对此类操作是没有意义的,不如新增一个执行配置

管理端开发配置及集成

这里仅以springboot为例:

  • 添加依赖,如果有maven私服建议放到私服
    <dependency>
        <groupId>org.quartz-scheduler.internal</groupId>
        <artifactId>quartz-client</artifactId>
        <version>2.3.2</version>
        <!-- 这是本地引入,建议放到私服-->
        <scope>system</scope>
        <systemPath>${pom.basedir}/src/main/resources/lib/quartz-client-2.3.2.jar</systemPath>
    </dependency>
  • 启动类需要排除自动装配
// 这一行是重点!
@SpringBootApplication(exclude = {QuartzAutoConfiguration.class})
public class MeeAdminApplication {
	/**
	 * 日志
	 */
	private static final Logger LOG= LoggerFactory.getLogger(MeeAdminApplication.class);

	public static void main(String[] args)throws Exception {
		ConfigurableApplicationContext application = SpringApplication.run(MeeAdminApplication.class, args);
		Environment env = application.getEnvironment();
		String ip = InetAddress.getLocalHost().getHostAddress();
		String port = env.getProperty("server.port");
		String path = env.getProperty("server.servlet.context-path");
		LOG.info("\n\t----------------------------------------------------------\n\t" +
				"Application MeeAdminApplication is running!\n\t" +
				"Local: \t\thttp://localhost:" + port + path + "/\n\t" +
				"External: \thttp://" + ip + ":" + port + path + "/\n\t" +
				"----------------------------------------------------------");
	}

}
  • 需要配置一个实例以使用
@Service
public final class QrtzJobServiceImpl implements QrtzJobService {

    /**
     *   日志
     */
    private static final Logger LOG = LoggerFactory.getLogger(QrtzJobServiceImpl.class);
    
    /**
     * quartz定时任务api
     */
    private final Scheduler scheduler;

    public QrtzJobServiceImpl(DataSource dataSource) {
        this.scheduler = new StdScheduler(dataSource);
    }
}
  • 调用sdk
    @Override
    public MeeResult<Integer> updateJobState(String job_id,String state) {
        Object[] result = scheduler.updateJobStateInAll(job_id,state);
        int updateCount = (int)result[0];
        if(updateCount>0){
            return ResultBuild.build(updateCount);
        }else{
            return ResultBuild.fail((String)result[1]);
        }
    }

Scheduler 提供了多种多样的api,注意部分接口的区别:

    如果管理端执行端一体 则无需引入client依赖(quartz-client),也无需在启动类中排除自动装配(QuartzAutoConfiguration),使用sdk也无需使用构造方式传入database,仅此即可:

    @Autowired
    private Scheduler scheduler;

执行端开发配置及集成

  • 引入依赖同时排除原生Quartz
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-quartz</artifactId>
            <version>${spring-boot-current.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.quartz-scheduler</groupId>
                    <artifactId>quartz</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.quartz-scheduler.internal</groupId>
            <artifactId>quartz-core</artifactId>
            <version>2.3.2</version>
            <!-- 这是本地引入,建议放到私服-->
            <scope>system</scope>
            <systemPath>${pom.basedir}/src/main/resources/lib/quartz-core-2.3.2.jar</systemPath>
        </dependency>
  • 添加依赖配置项
### ----------- quartz ------------------
spring.quartz.job-store-type=jdbc
spring.quartz.properties.org.quartz.jobStore.class=org.springframework.scheduling.quartz.LocalDataSourceJobStore
spring.quartz.properties.org.quartz.jobStore.clusterCheckinInterval=6000
spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.jdbcjobstore.impl.org.quartz.StdJDBCDelegate
spring.quartz.properties.org.quartz.jobStore.isClustered=true
# 表名前缀
spring.quartz.properties.org.quartz.jobStore.tablePrefix=QRTZ_
spring.quartz.properties.org.quartz.scheduler.instanceName=${spring.application.name}
#spring.quartz.properties.org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
spring.quartz.properties.org.quartz.threadPool.class=org.quartz.impl.MeeThreadPool
# 线程数配置
spring.quartz.properties.org.quartz.threadPool.threadCount=10
spring.quartz.properties.org.quartz.threadPool.threadPriority=5
# 綫程继承初始化线程的上下文类加载器
spring.quartz.properties.org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true
#Whether to enable pessimistic lock to control trigger concurrency in the cluster 是否启用悲观锁来控制集群中的触发并发
spring.quartz.properties.org.quartz.jobStore.acquireTriggersWithinLock=true

    配置项里面 要注意线程数的配置,如果使用的 MeeThreadPoolthreadCount为最大线程数,核心线程数 threadCount-2 ,最少为2,具体多少按实际CPU核心个数以及是否是IO密集型还是CPU密集型来配置即可~
其次要注意 tablePrefix 如果表名有变更则按照变更后的表名前缀配置即可

  • 定义一个任务
    • 如果使用的是spring提供的QuartzJobBean来开发:
      import com.mee.quartz.util.DateUtil;
      import org.quartz.JobExecutionContext;
      import org.quartz.JobExecutionException;
      import org.quartz.impl.QrtzExecute;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.scheduling.quartz.QuartzJobBean;
      
      import javax.sql.DataSource;
      
      
        public class ATestJob extends QuartzJobBean {
      
        private static final Logger log = LoggerFactory.getLogger(ATestJob.class);
      
          @Override
          protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
              try {
                  log.info("===>ATestJob::executeInternal {}-{} : {}-{}<===" ,context.getJobId(),context.getExecuteId(),context.getJobType(),context.getJobClassName());
              } catch (Exception e) {
                  throw new JobExecutionException(e);
              }
          }
      
      }
    
    • 如果使用的是Quartz提供的Job接口来开发,也可:
      import org.quartz.Job;
      import org.quartz.JobExecutionContext;
      import org.quartz.JobExecutionException;
      import org.quartz.impl.QrtzExecute;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      
      import java.util.concurrent.TimeUnit;
      
      public class Job01TestService  implements Job {
      
      private static final Logger LOGGER = LoggerFactory.getLogger(Job01TestService.class);
      
      @Override
      public void execute(JobExecutionContext context) throws JobExecutionException {
          LOGGER.info("=>>{}-{}.{}-{}",context.getJobId(),context.getExecuteId(),context.getJobType(),context.getJobClassName());
      }
    }
    
    

以上两种方式皆可,需要注意的是,不管是继承 QuartzJobBean 还是实现的 ``Job,均无需将类著名为spring bean类(@Service or @Component),Quartz内部自会创建任务类为spring bean ~

开发注意事项

  • 使用 quartz-client 添加的任务一般最晚会在 5秒 之后执行,因为任务轮询是 5秒 一轮询
  • 执行端执行异常(Quartz内的非业务的)的任务最晚在15S之后恢复任务执行,因为集群/缺火处理是 15秒 一轮询
  • 添加的任务如果不执行首先则要注意 spring.quartz.properties.org.quartz.scheduler.instanceName 配置项是否有配置,这个配置项对应 app 表中的 application 字段
  • 实际任务如有日志出现 任务延迟,建议排查宿主机资源是否占满,或者线程数配置是否合理

标签:00,Quartz,配置,spring,增强版,quartz,import,org,执行
From: https://www.cnblogs.com/funnyzpc/p/18540378

相关文章

  • 8.100ASK_T113-PRO 应用程序驱动LED灯 (/sys/class/gpio)
    前言1.利用LINUX内核的GPIO子统驱动LED灯.2. 编写应用程序控制LED灯的亮灭.3.不用写驱动程序,只写应用程序.1.原理图使用的是PE12这个IO口,计算一个IO编号: PE=4*32, IO编号=4*32+12=140.注解一下:PAX= 0*32+XPBX= 1*32+XPCX= 2*32+XPD......
  • [AGC005D] ~K Perm Counting
    题意求对于所有的\(i\)满足\(|P_i-i|\neqk\),的排列数量,对\(924844033\)取模。\(2\len\le2\times10^3,1\lek\len-1\)。Sol考虑转成\(n\timesn\)的网格图,那么就是所有\((i,i+k)\)以及\((i,i-k)\)的格子涂黑不能用。题意转化为在网格图里......
  • 题解:P10967 [IOI2000] 邮局(原始版)
    思路首先将坐标排序。定义\(dp_{i,j}\)为前\(i\)个村庄放\(j\)个邮局的前\(i\)个村庄的最小距离总和,\(f(i,j)\)表示村庄区间\([i,j]\)内放一个村庄时该区间的总和。转化式易得\(dp_{i}{j}=dp_{k}{j-1}+f(k+1,i),k\in[0,i)\)。则本题的难点就为求\(f(k-1,i)\)。......
  • 代码随想录算法训练营day43| 300.最长递增子序列 674. 最长连续递增序列 718. 最长
    学习资料:https://programmercarl.com/0300.最长上升子序列.html#算法公开课动态规划系列之子序列学习记录300.最长递增子序列(长度最少为1;dp[i]代表到i为止的最长子序列的长度;i的值根据i之前比如j的值来判断;每个地方都有可能获得最长长度)点击查看代码classSolution:def......
  • C语言网题目 1004: [递归]母牛的故事
    题目描述有一头母牛,它每年年初生一头小母牛。每头小母牛从第四个年头开始,每年年初也生一头小母牛。请编程实现在第n年的时候,共有多少头母牛?输入格式输入数据由多个测试实例组成,每个测试实例占一行,包括一个整数n(0<n<55),n的含义如题目中描述。n=0表示输入数据的结束,不做......
  • 实录:电话咨询数据库数据迁移“100” 个问题
    参加“央企”项目改造会后的,“数据库瞎想”这段时间国产数据库的话题频繁出现,新时代新需求,最近研究如何替换MySQL到国产数据库的过程中,发现有这样的需求。不乏一些老的系统,软件没人维护,之前编写软件的开发人员已经找不到踪影,应用系统的数据一直增长上涨,这些客户共同的特点,数......
  • 【就业反馈】2401期GIS开发特训营最高薪资13000元,人均1.4个offer
    总有人问想学GIS开发零基础能学会吗?学完真的能推荐就业吗?当然啦!!!新中地2401期GIS开发特训营毕业学员,就业反馈来啦!2401期GIS开发特训营,24年6月21日结业2401期就业数据反馈2401期就业数据反馈2401期班就业反馈图在新中地GIS开发特训营,很多人几乎都是从零......
  • 关于我、重生到500年前凭借C语言改变世界科技vlog.17——字符函数&&字符串函数
    文章目录1.字符函数1.1字符分类函数1.1.1islower1.2字符转换函数1.2.1tolower2.字符串函数2.1strlen2.2strcpy和strncpy2.3strcat和strncat2.4strcmp和strncmp2.5strstr2.6strtok2.7strerror希望读者们多多三连支持小编会继续更新你们的鼓励就是我前进的......
  • leetcode1008. 前序遍历构造二叉搜索树
    给定一个整数数组,它表示BST(即 二叉搜索树 )的 先序遍历 ,构造树并返回其根。保证 对于给定的测试用例,总是有可能找到具有给定需求的二叉搜索树。二叉搜索树 是一棵二叉树,其中每个节点, Node.left 的任何后代的值 严格小于 Node.val , Node.right 的任何后代的值......
  • PEF22554HTV3.1 英特尔intel 电信 IC 调帧器,线路接口单元(LIU) P-TQFP-144 在售20000PCS
    PEF22554HTV3.1是一款由英特尔(Intel)生产的电信IC调帧器,它可以与线路接口单元(LIU)一起使用。该调帧器的封装类型是P-TQFP-144。该调帧器适用于电信领域的应用,可以用于实现数据调制和解调功能,常见于传输和接收语音、数据和视频信号的通信设备中。型号:PEF22554HTV3.1类别:集成电路......