spring boot下定时任务quartz的集群使用
来源:互联网 发布:base64解码软件 编辑:程序博客网 时间:2024/06/05 10:04
单机模式下的定时任务调用很简单,有很多可实现的方案,这里不多说了。
这里说一下集群部署的情况下,定时任务的使用。这种情况下,quartz是一个比较好的选择。简单,稳定。
想象一下,现在有 A , B , C 3 台机器同时作为集群服务器对外统一提供 SERVICE :
A , B , C 3 台机器上各有一个 QUARTZ Job,它们会按照即定的 SCHEDULE 自动执行各自的任务。
先不说实现什么功能,这样的架构有点像多线程。由于三台SERVER 里都有 QUARTZ ,因此会存在重复处理 TASK 的现象。
一般外面的解决方案是只在一台 服务器上装 QUARTZ ,其它两台不装,这样的话其实就是单机了,quartz存在单点问题,一旦装有quartz的服务器宕了。服务就无法提供了。
当然还有其他一些解决方案,无非就是改 QUARTZ JOB 的代码了,这对程序开发人员来说比较痛苦;
而quartz本身提供了很好的集群方案。下面我们来说一下在spring boot下的集成:
quartz集群需要数据库的支持(JobStore TX或者JobStoreCMT),从本质上来说,是使集群上的每一个节点通过共享同一个数据库来工作的
一、准备工作:
到quartz官网下载最新的包:http://www.quartz-scheduler.org/downloads/
解压后,可以看到结构目录。在\docs\dbTables下选择合适你数据库的SQL执行文件,创建quartz集群需要的表(共11张表)
二、与springboot整合,这里假定你已经配好数据库连接等,项目能正常运行:
添加quartz的支持
<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz --> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.0</version> </dependency>
添加quartz配置:
#quartz集群配置# =========================================================================== # Configure Main Scheduler Properties 调度器属性 # ===========================================================================#调度标识名 集群中每一个实例都必须使用相同的名称 org.quartz.scheduler.instanceName=DefaultQuartzScheduler#ID设置为自动获取 每一个必须不同org.quartz.scheduler.instanceid=AUTO #============================================================================# Configure ThreadPool #============================================================================#线程池的实现类(一般使用SimpleThreadPool即可满足几乎所有用户的需求)org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool#指定线程数,至少为1(无默认值)(一般设置为1-100直接的整数合适)org.quartz.threadPool.threadCount = 25#设置线程的优先级(最大为java.lang.Thread.MAX_PRIORITY 10,最小为Thread.MIN_PRIORITY 1,默认为5) org.quartz.threadPool.threadPriority = 5#============================================================================# Configure JobStore #============================================================================# 信息保存时间 默认值60秒 org.quartz.jobStore.misfireThreshold = 60000#数据保存方式为数据库持久化org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX#数据库代理类,一般org.quartz.impl.jdbcjobstore.StdJDBCDelegate可以满足大部分数据库org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate#JobDataMaps是否都为String类型org.quartz.jobStore.useProperties = false#数据库别名 随便取org.quartz.jobStore.dataSource = myDS#表的前缀,默认QRTZ_org.quartz.jobStore.tablePrefix = QRTZ_#是否加入集群org.quartz.jobStore.isClustered = true#调度实例失效的检查时间间隔org.quartz.jobStore.clusterCheckinInterval = 20000#============================================================================# Configure Datasources #============================================================================#数据库引擎org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver#数据库连接org.quartz.dataSource.myDS.URL = jdbc:mysql://172.30.12.14:7001/rbl_test?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true#数据库用户org.quartz.dataSource.myDS.user = root#数据库密码org.quartz.dataSource.myDS.password = 123456#允许最大连接org.quartz.dataSource.myDS.maxConnections = 5#验证查询sql,可以不设置org.quartz.dataSource.myDS.validationQuery=select 0 from dual
添加任务注入的工厂类,否则任务注入会出错:
/* * 文件名:InvokingJobDetailDetailFactory.java 版权:Copyright by www.poly.com 描述: 修改人:gogym * 修改时间:2017年11月9日 跟踪单号: 修改单号: 修改内容: */package com.poly.rbl.schedule;import java.lang.reflect.Method;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import org.springframework.context.ApplicationContext;import org.springframework.scheduling.quartz.QuartzJobBean;public class InvokingJobDetailDetailFactory extends QuartzJobBean{ // 计划任务所在类 private String targetObject; // 具体需要执行的计划任务 private String targetMethod; private ApplicationContext ctx; @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { try { Object otargetObject = ctx.getBean(targetObject); Method m = null; try { m = otargetObject.getClass().getMethod(targetMethod); m.invoke(otargetObject); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } } catch (Exception e) { throw new JobExecutionException(e); } } public void setApplicationContext(ApplicationContext applicationContext) { this.ctx = applicationContext; } public void setTargetObject(String targetObject) { this.targetObject = targetObject; } public void setTargetMethod(String targetMethod) { this.targetMethod = targetMethod; }}
配置quartz:
/* * 文件名:QuartzConfig.java 版权:Copyright by www.poly.com 描述: 修改人:gogym 修改时间:2017年11月9日 跟踪单号: 修改单号: * 修改内容: */package com.poly.rbl.configuration;import java.io.IOException;import java.util.HashMap;import java.util.Map;import org.quartz.JobDetail;import org.quartz.Trigger;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.io.ClassPathResource;import org.springframework.scheduling.quartz.CronTriggerFactoryBean;import org.springframework.scheduling.quartz.JobDetailFactoryBean;import org.springframework.scheduling.quartz.SchedulerFactoryBean;import com.poly.rbl.schedule.InvokingJobDetailDetailFactory;@Configurationpublic class QuartzConfig{ // 配置文件路径 static final String QUARTZ_CONFIG = "properties/quartz.properties"; /** * Description: 定义调用对象和调用对象的方法 * * @param redisQuartzJob * @return * @see */ @Bean(name = "enjoyQuartzJobTask") public JobDetailFactoryBean enjoyQuartzJobTask() { //集群模式下必须使用JobDetailFactoryBean, MethodInvokingJobDetailFactoryBean 类中的 methodInvoking 方法,是不支持序列化的 JobDetailFactoryBean bean = new JobDetailFactoryBean(); bean.setName("enjoyQuartzJob");// 设置任务的名字 bean.setGroup("enjoyQuartzJobGroup");// 设置任务的分组,这些属性都可以存储在数据库中,在多任务的时候使用 bean.setDurability(true); bean.setRequestsRecovery(true); bean.setJobClass(InvokingJobDetailDetailFactory.class); Map<String, String> map = new HashMap<>(); map.put("targetObject", "enjoyQuartzJob");//任务所在的类 map.put("targetMethod", "enjoyWork");//具体执行任务的方法 bean.setJobDataAsMap(map); return bean; } /** * Description: 定义任务触发规则 * * @param redisTrigger * @return * @see */ @Bean(name = "enjoyQuartzJobTrigger") public CronTriggerFactoryBean enjoyQuartzJobTrigger(@Qualifier("enjoyQuartzJobTask") JobDetail enjoyQuartzJobTask) { CronTriggerFactoryBean trigger = new CronTriggerFactoryBean(); trigger.setJobDetail(enjoyQuartzJobTask); trigger.setCronExpression("0/5 * * * * ?");// cron表达式 trigger.setName("enjoyQuartzJobTrigger");// trigger的name return trigger; } @Bean public SchedulerFactoryBean schedulerFactoryBean(@Qualifier("enjoyQuartzJobTrigger") CronTriggerFactoryBean enjoyQuartzJobTrigger) throws IOException { SchedulerFactoryBean factory = new SchedulerFactoryBean(); // 用于quartz集群,QuartzScheduler 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 factory.setOverwriteExistingJobs(true); // QuartzScheduler 延时启动,应用启动完10秒后 QuartzScheduler 再启动 factory.setStartupDelay(10); // 直接使用配置文件,用于quartz集群,加载quartz数据源配置 factory.setConfigLocation(new ClassPathResource(QUARTZ_CONFIG)); factory.setAutoStartup(true); //集群需要通过QuartzJobBean注入,需要设置上下文 factory.setApplicationContextSchedulerContextKey("applicationContext"); // 注册触发器 Trigger[] triggers = {enjoyQuartzJobTrigger.getObject()}; factory.setTriggers(triggers); return factory; }}
JOB任务:
/* * 文件名:EnjoyQuartzJob.java 版权:Copyright by www.poly.com 描述: 修改人:gogym 修改时间:2017年11月9日 跟踪单号: 修改单号: * 修改内容: */package com.poly.rbl.schedule;import org.springframework.stereotype.Component;@Component("enjoyQuartzJob")public class EnjoyQuartzJob{ public void enjoyWork() { System.out.println("定时任务执行"); }}
启动即可看到数据库插入了任务相关的信息。集群完成。
需要注意的是:
当你运行水平集群时,时钟应当要同步,以免出现离奇且不可预知的行为。假如时钟没能够同步,Scheduler 实例将对其他节点的状态产生混乱。有几种简单的方法来保证时钟何持同步,而且也没有理由不这么做。最简单的同步计算机时钟的方式是使用某一个 Internet 时间服务器(Internet Time Server ITS)。
常用解决方案:
服务器中配置时间同步只要一台服务器同步互联网的时钟服务器,其它的服务以这台为时钟服务器!
Linux配置(局域网的客户端)
1、安装
yum install ntp (centos的安装方法)
2、先运行 # ntpdate 192.168.1.33 同步一次.
3、然后通过crontab计时器配置一个定时同步的任务,例如每月一号零点零分同步一次.代码如下:
# crontab -e //添下面一行,新建的定时任务文件保存在/var/spool/cron/下,以创建人的用户名命名
0 0 1 * * /etc/ntp/ntprsync.sh //每小时同步一次。
4、创建文件
# vi ntprsync.sh //内容如下#!/bin/sh/usr/sbin/ntpdate 192.168.1.33 //时钟服务器的IP/sbin/hwclock –w
5、设置权限 chmod 777 ntprsync.sh
6、注意防火墙的设置.
7、成功。
8、服务启动。
/sbin/service crond start //启动服务/sbin/service crond stop //关闭服务/sbin/service crond restart //重启服务/sbin/service crond reload //重新载入配置
- spring boot下定时任务quartz的集群使用
- spring boot环境下使用quartz设置定时任务
- Spring+Quartz定时任务集群环境下部署的解决方法
- spring下使用Quartz完成定时任务
- 使用spring 的Quartz 定时任务入门
- 使用Spring+Quartz的定时任务。
- Spring boot +Quartz +mongodb的分布式定时任务详解
- spring+quartz定时任务调度实现集群环境下的整合
- Spring Boot 定时任务之Quartz
- spring-quartz定时任务集群解决方案。
- Spring+quartz实现定时任务集群
- Spring Boot 定时任务的使用
- Spring Boot 定时任务的使用
- Spring Boot 定时任务的使用
- Spring Boot 定时任务的使用
- Spring Boot 定时任务的使用
- spring boot中定时任务的使用
- spring boot定时任务的使用
- 利用axis1 客户端调用cxf写的webservice接口
- 第一篇博客
- 盘点各种程序员常用的框架,看看你是否落伍了?
- ArrayList-Vector-LinkedList-泛型-增强for
- 数据库阿里连接池 druid配置详解 标签: druidspringjavaxml配置阿里池 2016-06-16 00:34 57532人阅读 评论(11) 收藏 举报 版权声明:本文为博主原创文
- spring boot下定时任务quartz的集群使用
- 模块API之register_module_notifier
- 中国软件网想举办【企服三会】结果玩大了...
- 天天都在数据驱动,你以为数据是天上掉下来的?
- 动力电池回收法规出炉丨IBM量子计算新突破丨iphone X冬天不能用?苹果:恩!
- vs2012+win8内核编译环境
- Linux之iptables详解
- Jenkins的关闭、重启
- xml-基础知识