概述
公司项目在发到生产后启了2个实例,导致调度同时执行,起先使用了事务隔离和数据库控制执行版本,不过不是很好,不是最佳的解决方案,查了资料Quartz本身支持多实例,稍加配置即可。
此篇文章在Spring boot下使用Quartz 基础上进行修改,建议阅读完之后再看
1. 下载quartz
官网
我用的是2.2.3
**2. 创建表 **
下载下来tar包后解压后打开
quartz-2.2.3docsdbTables
找到你需要的数据库sql文件执行
例如:我用的是PG,执行的是tables_postgres.sql文件里的sql
注意:2.3.0版本sql文件在quartz-2.3.0-SNAPSHOTsrcorgquartzimpljdbcjobstore
3. 新增配置文件
import java.util.Properties;
import javax.sql.DataSource;
import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
@Configuration
@AutoConfigureAfter(DruidAutoConfiguration.class)//在该类之后执行,为了使用dataSource,(DruidAutoConfiguration是连接数据库配置文件,参考文末)
public class QuartzConfig {
@Autowired
private DataSource dataSource;
/**
* 设置属性
*/
private Properties quartzProperties() {
Properties prop = new Properties();
//拉取trigger加锁
prop.put("org.quartz.jobStore.acquireTriggersWithinLock", "true");
prop.put("org.quartz.scheduler.instanceName", "quartzScheduler");
prop.put("org.quartz.scheduler.instanceId", "AUTO");
prop.put("org.quartz.scheduler.skipUpdateCheck", "true");
prop.put("org.quartz.scheduler.jmx.export", "true");
// Configure JobStore
// #JobDataMaps是否都为String类型
// prop.put("org.quartz.jobStore.useProperties", "true");//不要用,报错
prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");
// PG专用
prop.put("org.quartz.jobStore.driverDelegateClass",
"org.quartz.impl.jdbcjobstore.PostgreSQLDelegate");
// job注入datasource
// prop.put("org.quartz.jobStore.dataSource","druid");//#使用JNDI数据源的时候,数据源的名字
prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
// 开启集群
// #ture则此实例需要参加到集群中
prop.put("org.quartz.jobStore.isClustered", "true");
// #调度实例失效的检查时间间隔
prop.put("org.quartz.jobStore.clusterCheckinInterval", "20000");
// prop.put("org.quartz.jobStore.dataSource", "myDS");
// 这是 JobStore 能处理的错过触发的 Trigger 的最大数量
prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1");
// #容许的最大作业延长时间
prop.put("org.quartz.jobStore.misfireThreshold", "60000");
//值为 true 时告知 Quartz(当使用 JobStoreTX 或 CMT)
//调用 JDBC 连接的 setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE) 方法
//这有助于阻止某些数据库在高负载和长时间事物时锁的超时。
prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true");
prop.put("org.quartz.jobStore.selectWithLockSQL",
"SELECT * FROM {0}LOCKS WHERE LOCK_NAME = ? FOR UPDATE");
// Configure ThreadPool
prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
prop.put("org.quartz.threadPool.threadCount", "50");
prop.put("org.quartz.threadPool.threadPriority", "5");
prop.put("org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread",
"true");
/*
* prop.put("org.quartz.dataSource.myDS.driver", myDSDriver);
* prop.put("org.quartz.dataSource.myDS.URL", myDSURL);
* prop.put("org.quartz.dataSource.myDS.user", myDSUser);
* prop.put("org.quartz.dataSource.myDS.password", myDSPassword);
* System.out.println("myDSMaxConnections:" + myDSMaxConnections);
* prop.put("org.quartz.dataSource.myDS.maxConnections",
* myDSMaxConnections);
*/
prop.put("org.quartz.plugin.triggHistory.class",
"org.quartz.plugins.history.LoggingJobHistoryPlugin");
prop.put("org.quartz.plugin.shutdownhook.class",
"org.quartz.plugins.management.ShutdownHookPlugin");
prop.put("org.quartz.plugin.shutdownhook.cleanShutdown", "true");
return prop;
}
@Bean
public SchedulerFactoryBean schedulerFactoryBean() {//得到schedulerFactoryBean,并注入多实例参数
SchedulerFactoryBean factory = new SchedulerFactoryBean();
// this allows to update triggers in DB when updating settings in config
// file:
// 用于quartz集群,QuartzScheduler
// 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
factory.setOverwriteExistingJobs(true);
// 用于quartz集群,加载quartz数据源
factory.setDataSource(dataSource);
// QuartzScheduler 延时启动,应用启动完10秒后 QuartzScheduler 再启动
factory.setStartupDelay(10);
// 用于quartz集群,加载quartz数据源配置
factory.setQuartzProperties(quartzProperties());
factory.setAutoStartup(true);
// applicationContextSchedulerContextKey:
// 是org.springframework.scheduling.quartz.SchedulerFactoryBean这个类中把spring上下
// 文以key/value的方式存放在了quartz的上下文中了,可以用applicationContextSchedulerContextKey所定义的key得到对应的spring上下文
// factory.setApplicationContextSchedulerContextKey("applicationContext");
// factory.setConfigLocation(new
// FileSystemResource(this.getClass().getResource("/quartz.properties").getPath()));
return factory;
}
//得到scheduler
@Bean
public Scheduler scheduler(SchedulerFactoryBean schedulerFactoryBean) {
return schedulerFactoryBean.getScheduler();
}
}
4. 修改ServiceImpl实现类的scheduler注入方式
一些调度器操作
@Service
@Slf4j
public class SchedulerServiceImpl implements SchedulerService {
@Autowired
private
Scheduler scheduler;
内容省略,跟上一遍文章一样。
}
文末. (仅供参考)
连接数据库的配置文件
DruidAutoConfiguration.java
import java.sql.SQLException;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.alibaba.druid.pool.DruidDataSource;
@Configuration
@EnableConfigurationProperties(DruidProperties.class)
@ConditionalOnClass(DruidDataSource.class)
@ConditionalOnProperty(prefix = "druid", name = "url")
@AutoConfigureBefore(DataSourceAutoConfiguration.class)
public class DruidAutoConfiguration {
@Autowired
private DruidProperties properties;
@Bean
public DataSource dataSource() {
System.out.println(DataConverterUtil.object2Json(properties));
System.out.println(DataConverterUtil.object2Json(properties));
System.out.println(DataConverterUtil.object2Json(properties));
System.out.println(DataConverterUtil.object2Json(properties));
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(properties.getUrl());
dataSource.setUsername(properties.getUsername());
dataSource.setPassword(properties.getPassword());
if (properties.getInitialSize() > 0) {
dataSource.setInitialSize(properties.getInitialSize());
}
if (properties.getMinIdle() > 0) {
dataSource.setMinIdle(properties.getMinIdle());
}
if (properties.getMaxActive() > 0) {
dataSource.setMaxActive(properties.getMaxActive());
}
dataSource.setTestOnBorrow(properties.isTestOnBorrow());
try {
dataSource.init();
} catch (SQLException e) {
throw new RuntimeException(e);
}
return dataSource;
}
}
DruidProperties .java
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "druid")
public class DruidProperties {
private String url;
private String username;
private String password;
private String driverClass;
private int
maxActive;
private int
minIdle;
private int
initialSize;
private boolean testOnBorrow;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getDriverClass() {
return driverClass;
}
public void setDriverClass(String driverClass) {
this.driverClass = driverClass;
}
public int getMaxActive() {
return maxActive;
}
public void setMaxActive(int maxActive) {
this.maxActive = maxActive;
}
public int getMinIdle() {
return minIdle;
}
public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
}
public int getInitialSize() {
return initialSize;
}
public void setInitialSize(int initialSize) {
this.initialSize = initialSize;
}
public boolean isTestOnBorrow() {
return testOnBorrow;
}
public void setTestOnBorrow(boolean testOnBorrow) {
this.testOnBorrow = testOnBorrow;
}
}
application.properties
## 需è¦ä¿®æ”¹æ•°æ®åº“连接信æ¯
druid.url=jdbc:postgresql://11.11.11.11:7443/test
druid.driver-class=org.postgresql.Driver
druid.username=testdata
druid.password=yang1234
druid.initial-size=1
druid.min-idle=1
druid.max-active=20
druid.test-on-borrow=true
喜欢请点赞,不懂请留言^^
最后
以上就是鳗鱼皮带为你收集整理的Spring boot下使用Quartz--多实例解决方案的全部内容,希望文章能够帮你解决Spring boot下使用Quartz--多实例解决方案所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复