Quartz集群增强版_00.How to use?(如何使用)
Quartz集群增强版_00.How to use?(如何使用)
开源地址 https://github.com/funnyzpc/quartz
表的基本结构
总的来说任务的配置及开发基本遵从上图的表的基本关系,除 app 以及 node 之外均需要手动手动配置,app 及 node 在执行端启动的时候会自动生成对应 app 以及 node 的数据 ~
后管配置
先看一下后管的基本页面~
因为 app 与 node 是一对多的关系,这里就放到一个page下:

这里需要说明的是
app与node一般无需新增,如果特殊情况下请参照下图:
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
配置项里面 要注意线程数的配置,如果使用的 MeeThreadPool 则threadCount为最大线程数,核心线程数 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字段 - 实际任务如有日志出现 任务延迟,建议排查宿
主机资源是否占满,或者线程数配置是否合理 
Quartz集群增强版_00.How to use?(如何使用)的更多相关文章
- Quartz集群
		
为什么选择Quartz: 1)资历够老,创立于1998年,比struts1还早,但是一直在更新(27 April 2012: Quartz 2.1.5 Released),文档齐全. 2)完全由Jav ...
 - 项目中使用Quartz集群分享--转载
		
项目中使用Quartz集群分享--转载 在公司分享了Quartz,发布出来,希望大家讨论补充. CRM使用Quartz集群分享 一:CRM对定时任务的依赖与问题 二:什么是quartz,如何使用, ...
 - 使用sqlserver搭建高可用双机热备的Quartz集群部署【附源码】
		
一般拿Timer和Quartz相比较的,简直就是对Quartz的侮辱,两者的功能根本就不在一个层级上,如本篇介绍的Quartz强大的序列化机制,可以序列到 sqlserver,mysql,当然还可以在 ...
 - Springboot2.X集成Quartz集群
		
为什么要使用Quzrtz集群 在项目进行集群部署时,如果业务在执行中存在互斥关系,没有对定时任务进行统一管理,就会引起业务的多次执行,不能满足业务要求.这时就需要对任务进行管理,要保证一笔业务在所有的 ...
 - 双机热备的Quartz集群
		
sqlserver搭建高可用双机热备的Quartz集群部署[附源码] 一般拿Timer和Quartz相比较的,简直就是对Quartz的侮辱,两者的功能根本就不在一个层级上,如本篇介绍的Quartz ...
 - quartz集群报错but has failed to stop it. This is very likely to create a memory leak.
		
quartz集群报错but has failed to stop it. This is very likely to create a memory leak. 在一台配置1核2G内存的阿里云服务器 ...
 - Quartz集群配置
		
先看看quartz的持久化基本介绍: 引用 1 大家都清楚quartz最基本的概念就是job,在job内调用具体service完成具体功能,quartz需要把每个job存储起来,方便调度,quartz ...
 - Quartz集群原理及配置应用
		
1.Quartz任务调度的基本实现原理 Quartz是OpenSymphony开源组织在任务调度领域的一个开源项目,完全基于Java实现.作为一个优秀的开源调度框架,Quartz具有以下特点: (1) ...
 - quartz集群调度机制调研及源码分析---转载
		
quartz2.2.1集群调度机制调研及源码分析引言quartz集群架构调度器实例化调度过程触发器的获取触发trigger:Job执行过程:总结:附: 引言 quratz是目前最为成熟,使用最广泛的j ...
 - (4) Spring中定时任务Quartz集群配置学习
		
原 来配置的Quartz是通过spring配置文件生效的,发现在非集群式的服务器上运行良好,但是将工程部署到水平集群服务器上去后改定时功能不能正常运 行,没有任何错误日志,于是从jar包.JDK版本. ...
 
随机推荐
- 100ASK_IMX6ULL arm板子如何移植刷卡器
			
最近为了在arm板子上移植刷卡器,比较简单,但也遇到了坑,现在和大家分享下. 购买刷卡器 某宝很多,应该选哪一种呢? 一口君一共买了4种刷卡器,有2种可以用,还有2种不能用. 下图为最方便的一款,一口 ...
 - C语言/实现MD5加密
			
本文详细视频讲解,已经发布到B站 https://www.bilibili.com/video/BV1uy4y1p7on/ 更多仔细,请关注公众号:一口Linux 一.摘要算法 摘要算法又称哈希算法. ...
 - Win32 拆分窗口
			
前两天学习了MFC的拆分窗口,今天来学习Win32 SDK下如何拆分窗口. win32是没有像MFC那样直接有函数方法拆分窗口,只能自己处理了. 1.在WM_CREATE消息中创建两个控件,TreeV ...
 - Typora 上传到 Github 实现笔记同步管理
			
首先在 Github 上 new 一个 repository ,我建的名称是 md_notes 然后在本地 terminal 中启动以下命令新建一个 ssh key ssh-keygen -o 生成 ...
 - 最详细STL(三)list
			
list就是链表啦,他的一个结点由两个指针域,一个数据域组成.list可以在任何位置以O(n)的复杂度插入元素,头部和尾部的插入的复杂度为O(1).然而list也有一个致命的缺点,因为链表的空间申请是 ...
 - 在 Windows 中启用 Administrator 帐户
			
打开管理员终端. 启用: net user administrator /active:yes 关闭: net user administrator /active:no
 - Python with 语句的用法
			
with 语句是Python中用于简化资源管理的一种语法结构,通常与上下文管理器(Context Manager)一起使用.上下文管理器提供了一种机制,用于确保资源在使用完毕后能够被正确释放,例如文件 ...
 - Linux (Debian)  安装MySQL 后如何获取登录密码
			
树莓派安装MySQL后获取登录密码 树莓派基于Debian系统. 成功安装MySQL后 su root vim /etc/mysql/debian.cnf 其中 user 和 password 就是你 ...
 - js 翻译 c# 注意事项
			
1. split('') 在 c# 是不可以 .Split("") 的 要写 ToCharArray() 更新: 2021-09-25, split('') 是不好的写法, es6 ...
 - 图形化客户端工具——Navicat
			
1.下载 下载地址:https://wwb.lanzoub.com/i4TuZ0g3okod 破解: 解压后有两个文件 先点击第一个文件依次安装 安装完成后 ...
 
			
		


