由于希望可以在集群环境中运行定时job,但考虑到多个job实例有可能带来job重复执行的问题,新项目的job打算从原生的spring task实现改成quartz job实现,并采用jdbc的存储方式。

如果是把quartz的表初始化到原先springboot配置的同一个数据库,并没有太多问题,但考虑到这样做会在业务表中插入很多不相关的表,决定把quartz的表建在单独的一个库中。查了quartz和springboot文档,quartz中的配置

org.quartz.jobStore.dataSource=NAME

org.quartz.dataSource.NAME.driver
org.quartz.dataSource.NAME.URL
org.quartz.dataSource.NAME.user
org.quartz.dataSource.NAME.password
org.quartz.dataSource.NAME.maxConnections
org.quartz.dataSource.NAME.validationQuery
org.quartz.dataSource.NAME.validateOnCheckout
org.quartz.dataSource.NAME.discardIdleConnectionsSeconds

但集成到springboot中,在application.yml用了自己的配置

By default, an in-memory JobStore is used. However, it is possible to configure a JDBC-based store if a DataSource bean is available in your application and if the spring.quartz.job-store-type property is configured accordingly, as shown in the following example:

spring.quartz.job-store-type=jdbc
When the JDBC store is used, the schema can be initialized on startup, as shown in the following example: spring.quartz.jdbc.initialize-schema=always

Advanced Quartz configuration properties can be customized using spring.quartz.properties.*.

查了些资料后,application.yml配置如下

spring:
redis:
host: localhost
database: 2
password: guanlouyi
port: 6399
datasource:
url: jdbc:mysql://192.168.40.241:3306/fintech_public?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true
username: root
password: 20.112@,l
driver-class-name: com.mysql.jdbc.Driver
quartz:
job-store-type: jdbc
jdbc:
initialize-schema: always
properties:
org:
quartz:
dataSource:
quartzDS:
driver: com.mysql.jdbc.Driver
URL: jdbc:mysql://192.168.40.241:3306/fintech_quartz?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true
user: root
password: 20.112@,l
scheduler:
instanceName: clusteredScheduler
instanceId: AUTO
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
dataSource: quartzDS
tablePrefix: QRTZ_
isClustered: true
clusterCheckinInterval: 10000
useProperties: false
threadPool:
class: org.quartz.simpl.SimpleThreadPool
threadCount: 10
threadPriority: 5
threadsInheritContextClassLoaderOfInitializingThread: true

但是这样配置的datasouce并不生效,用的还是原来的数据库。查了些网上的资料,要给scheduler单独的dataSource,而且发现springboot文档里有

To have Quartz use a DataSource other than the application’s main DataSource, declare a DataSource bean, annotating its @Bean method with @QuartzDataSource. Doing so ensures that the Quartz-specific DataSource is used by both the SchedulerFactoryBean and for schema initialization.

于是application.yml改成(spring.datasource去掉改成@Bean@Primary形式,不这样会报同时存在两个dataSrouce,然后把quartz.dataSource的配置去掉了,加@QuartzDataSource注入:自以为)

spring:
redis:
host: localhost
database: 2
password: guanlouyi
port: 6399
quartz:
job-store-type: jdbc
jdbc:
initialize-schema: never
properties:
org:
quartz:
dataSource:
scheduler:
instanceName: clusteredScheduler
instanceId: AUTO
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
tablePrefix: QRTZ_
isClustered: false
clusterCheckinInterval: 10000
useProperties: true
threadPool:
class: org.quartz.simpl.SimpleThreadPool
threadCount: 10
threadPriority: 5
threadsInheritContextClassLoaderOfInitializingThread: true datasource:
primary:
url: jdbc:mysql://192.168.40.241:3306/fintech_public?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true
username: root
password: 20.112@,l
driver-class-name: com.mysql.jdbc.Driver
scheduler:
url: jdbc:mysql://192.168.40.241:3306/fintech_quartz
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver

代码加上DataSourceConfig

    @Bean
@Primary
@ConfigurationProperties(prefix = "datasource.primary")
public DataSourceProperties primaryDataSourceProperties() {
return new DataSourceProperties();
} @Bean
@ConfigurationProperties(prefix = "datasource.scheduler")
public DataSourceProperties quartzDataSourceProperties() {
return new DataSourceProperties();
} @Bean(name = "primaryDataSource")
public DataSource primaryDataSource() {
return primaryDataSourceProperties().initializeDataSourceBuilder().type(HikariDataSource.class).build();
} @Bean(name = "quartzDataSource")
@ConfigurationProperties(prefix = "datasource.scheduler")
@QuartzDataSource
public DataSource quartzDataSource() {
DataSource datasource = quartzDataSourceProperties().initializeDataSourceBuilder().type(HikariDataSource.class)
.build();
return datasource;
}

启动报错:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'adminEventsMapper' defined in file [E:\git\fintech-parent\fintech-microservice-dao\target\classes\com\panshi\fintech\microservice\dao\mapper\AdminEventsMapper.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required

分析:可能是把spring.datasource去掉,用@Bean和@Primary的形式生成的DataSource顺序发生了改变,导致sqlSessionFactory和sqlSessionTemplate没有生成,mybatis的Mapper初始化时没有找到,在Mapper注入的地方加上@Lazy可以解决,但不打算采用此方法。后来网上看到有人也自己初始化sqlSessionFactory和sqlSessionTemplate,于是加上:

    /**
* 创建 SqlSessionFactory
*/
@Bean(name = "sqlSessionFactory")
@Primary
public SqlSessionFactory primarySqlSessionFactory(@Qualifier("primaryDataSource") DataSource dataSource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
// bean.setMapperLocations(new
// PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/db1/*.xml"));
return bean.getObject();
} @Bean(name = "sqlSessionTemplate")
@Primary
public SqlSessionTemplate primarySqlSessionTemplate(
@Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}

这个问题解决,但又出现另一个问题:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'quartzScheduler' defined in class path resource [org/springframework/boot/autoconfigure/quartz/QuartzAutoConfiguration.class]: Invocation of init method failed; nested exception is org.quartz.SchedulerConfigException: DataSource name not set.

后来折腾了老半天,还是把dataSource加回application.yml

eureka:
client:
serviceUrl:
defaultZone: http://localhost:8762/eureka
logging:
path: /opt
level:
ROOT: DEBUG
com.panshi.fintech: DEBUG
spring:
redis:
host: localhost
database: 2
password: guanlouyi
port: 6399
quartz:
job-store-type: jdbc
jdbc:
initialize-schema: always
properties:
org:
quartz:
dataSource:
quartzDataSource:
driver: com.mysql.jdbc.Driver
URL: jdbc:mysql://192.168.40.241:3306/fintech_quartz
user: root
password: 20.112@,l
scheduler:
instanceName: clusteredScheduler
instanceId: AUTO
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
tablePrefix: QRTZ_
isClustered: false
dataSource: quartzDataSource
clusterCheckinInterval: 10000
useProperties: true
threadPool:
class: org.quartz.simpl.SimpleThreadPool
threadCount: 10
threadPriority: 5
threadsInheritContextClassLoaderOfInitializingThread: true
datasource:
primary:
url: jdbc:mysql://192.168.40.241:3306/fintech_public?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true
username: root
password: 20.112@,l
driver-class-name: com.mysql.jdbc.Driver
scheduler:
url: jdbc:mysql://192.168.40.241:3306/fintech_quartz
username: root
password: 20.112@,l
driver-class-name: com.mysql.jdbc.Driver
file:
path: /opt
access-path: http://localhost
swagger:
enabled: true

原来这个配置还是需要的,但同时还要@Bean生成schedule的dataSource,同时加上

@QuartzDataSource

springboot 2.x 集成quartz持久化到一个单独的dataSource时遇到的坑的更多相关文章

  1. 记录一个修改application.properties时遇到的坑

    有一个需求是会频繁修改配置文件中的常量,为了方便就会用unzip解压war包,修改propertites中的值后重新打war 包,部署,但是发现修改的值没有起作用,,一直在纠结...后来发现其实在编译 ...

  2. SpringBoot 1.5.x 集成 Quartz 任务调度框架

    Quartz 有分 内存方式 和 数据库方式 内存方式任务信息保存在内存中, 停机会丢失, 需手动重新执行, 数据库方式: 任务信息保存在数据库中, 重点是支持集群. 内存方式 RAMJobStore ...

  3. SpringBoot集成Quartz(解决@Autowired空指针Null问题即依赖注入的属性为null)

    使用spring-boot作为基础框架,其理念为零配置文件,所有的配置都是基于注解和暴露bean的方式. Quartz的4个核心概念: 1.Job表示一个工作,要执行的具体内容.此接口中只有一个方法v ...

  4. SpringBoot集成Quartz实现定时任务

    1 需求 在我的前后端分离的实验室管理项目中,有一个功能是学生状态统计.我的设计是按天统计每种状态的比例.为了便于计算,在每天0点,系统需要将学生的状态重置,并插入一条数据作为一天的开始状态.另外,考 ...

  5. SpringBoot定时任务 - 集成quartz实现定时任务(单实例和分布式两种方式)

    最为常用定时任务框架是Quartz,并且Spring也集成了Quartz的框架,Quartz不仅支持单实例方式还支持分布式方式.本文主要介绍Quartz,基础的Quartz的集成案例本,以及实现基于数 ...

  6. springboot自带定时任务和集成quartz

    1,springboot自带的定时任务  默认是单线程 有这个依赖就可以 <dependency> <groupId>org.springframework.boot</ ...

  7. SpringBoot整合任务调度框架Quartz及持久化配置

    目录 本篇要点 SpringBoot与Quartz单机版快速整合 引入依赖 创建Job 调度器Scheduler绑定 自动配置,这里演示SimpleScheduleBuilder 手动配置,这里演示C ...

  8. quartz的持久化任务调度使用应用的dataSource

    Quartz提供两种基本作业存储类型--->第一种类型叫做RAMJobStore:     最佳的性能,因为内存中数据访问最快     不足之处是缺乏数据的持久性,当程序路途停止或系统崩溃时,所 ...

  9. SpringBoot12 QueryDSL01之QueryDSL介绍、springBoot项目中集成QueryDSL

    1 QueryDSL介绍 1.1 背景 QueryDSL的诞生解决了HQL查询类型安全方面的缺陷:HQL查询的扩展需要用字符串拼接的方式进行,这往往会导致代码的阅读困难:通过字符串对域类型和属性的不安 ...

  10. SpringBoot(十)_springboot集成Redis

    Redis 介绍 Redis是一款开源的使用ANSI C语言编写.遵守BSD协议.支持网络.可基于内存也可持久化的日志型.Key-Value高性能数据库. 数据模型 Redis 数据模型不仅与关系数据 ...

随机推荐

  1. 1.2 HELLO 三角形

    这一节,我觉得是相当有难度的.渲染一个三角形,就需要介绍GLSL语言,图形渲染管线(Graphics Pipeline)以及着色器(Shader),标准化设备坐标(NDC)等诸多概念. 图形渲染管线和 ...

  2. 利用cv2.morphologyEx提取图像边界

    cv2.morphologyEx(image, cv2.MORPH_GRADIENT, SE)可以参考这篇博客cv2.MORPH_GRADIENT:形态学梯度(morph-grad),可以突出团块(b ...

  3. 【信创问题】解决东方通(TongWeb)报错 java.lang.NoClassDefFoundError: javax/persistence/spi/PersistenceProvider

    写在前边 今天帮现场同事定位问题,情况是项目同事使用东方通(TongWeb7.0)部署公司项目时,出现以下报错导致服务启动失败. 简单排查了下发现:war包内WEB-INF/lib/javax.per ...

  4. 蜘点云原生之 KubeSphere 落地实践过程

    作者:池晓东,蜘点商业网络服务有限公司技术总监,从事软件开发设计 10 多年,喜欢研究各类新技术,分享技术. 来源:本文由 11 月 25 日广州站 meetup 中讲师池晓东整理,整理于该活动中池老 ...

  5. KubeSphere 社区双周报 | Java functions framework 支持 SkyWalking | 2023.8.4-8.17

    KubeSphere 社区双周报主要整理展示新增的贡献者名单和证书.新增的讲师证书以及两周内提交过 commit 的贡献者,并对近期重要的 PR 进行解析,同时还包含了线上/线下活动和布道推广等一系列 ...

  6. OpenFunction 0.7.0 发布: OpenFunction Gateway、多语言及 Helm 安装支持

    OpenFunction 是一个开源的云原生 FaaS(Function as a Service,函数即服务)平台,旨在帮助开发者专注于业务逻辑的研发.在过去的几个月里,OpenFunction 社 ...

  7. AI五子棋_07 落子点四周棋形获取

    AI五子棋 第七步 恭喜你到达第七步! 到这一步,你对战场环境就有了充分的了解.下面我们准备打造机器大脑了.你可能已经有你自己的想法了,不过别着急,先跟着我的思路做.我会提示你解决一些基本的问题. 棋 ...

  8. 轻量级网络-MobileNetv1 论文解读

    1.相关工作 标准卷积 分组卷积 从 Inception module 到 depthwise separable convolutions 2.MobileNets 结构 2.1,深度可分离卷积 D ...

  9. JS 本地存储 localStorage 操作总结

    现在前端做数据存储,跨页面传值,localStorage是一个很好的方式,以键值对的方式存储,也方便取值赋值,下面说一说使用方法和一些常见的使用技巧. 1.存值共有3种方式,localStorage相 ...

  10. java可变参数案例学习

    /* ** 可变参数案例 */ public class changeVar { public static void main(String[] args) { printMax(34, 3, 2, ...