很久以前就用过quartz,现在重新用起,主要实现集群方式启动,并且支持多数据源注入到job中。网上demo很多,方法大同小异。但关于数据源注入的深入介绍不多,不错的文章:《spring-boot-2.0.3之quartz集成,数据源问题,源码探究》,作者关于quartz有3篇,都值得一看。
总结一下:mybatis不是必须的,springboot会自动将数据源注入到quartz(前提是你的配置正确)。本地化的job类也不是必须的,创建一个类主要是控制任务时传参数。
理论上来说,在数据库中建好quartz的表,在pom中加入相关依赖,配置好quartz的属性,无需额外编码,就可以让quartz跑起来。只是这种情况没有任何任务,需要对任务进行增删改启停就需要实现一个service来操作job,这个类网上的demo几乎都一样,实现控制job的方法都是调用quartz的方法。
要记录的有几点:
1、我还没有彻底弄清job的各种特性,包括任务的调度等,先从基本功能开始,满足业务需要即可。
2、踩了两个坑,一个是依赖问题,在IDEA中可以顺畅的跑,但部署到服务器运行就会报错(mybatis相关)。琢磨了很久,没找到原因,无意中发现可能是依赖冲突导致,于是从零开始,力求最少依赖方式,我的依赖见下。第二个坑,使用了企业自研的分布式数据库(mysql),结果本机mysql正常,连企业数据库就报错:"Unknown column '0x' in 'field list'。最后dba查日志发现是在向trigger表插入数据时blob字段没按要求将0x用引号包起来。
3、接下来还需要尝试使用jar进行任务定制,实现不动框架就可以对job进行定制。
附pom及properties:
pom.xml,其中的mybatis是因为job要访问业务数据库才加入的依赖。
<dependencies> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>RELEASE</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>RELEASE</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version> </dependency> <dependency> <groupId>commons-net</groupId> <artifactId>commons-net</artifactId> <version>3.6</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-quartz --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> <version>RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc8</artifactId> <version>12.2.0.1</version> </dependency> </dependencies>
application.properties。使用了druid的主从数据源(需要定义额外的配置类),quartz的表格部署在主库上,springboot默认将主库数据源注入到了quartz。
#quartz相关属性配置 spring.quartz.properties.org.quartz.scheduler.instanceName=myTasks spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate spring.quartz.properties.org.quartz.jobStore.tablePrefix=QRTZ_ spring.quartz.properties.org.quartz.jobStore.isClustered=true spring.quartz.properties.org.quartz.jobStore.clusterCheckinInterval=10000 spring.quartz.properties.org.quartz.jobStore.useProperties=false spring.quartz.properties.org.quartz.jobStore.dataSource=qzDS spring.quartz.properties.org.quartzthreadPool.class=org.quartz.simpl.SimpleThreadPool spring.quartz.properties.org.quartzthreadPool.threadCount=10 spring.quartz.properties.org.quartzthreadPool.threadPriority=5 spring.quartz.properties.org.quartzthreadPool.threadsInheritContextClassLoaderOfInitializingThread=true #数据库方式 spring.quartz.job-store-type=JDBC #初始化表结构 spring.quartz.jdbc.initialize-schema=NEVER ## mysql 数据源配置,主库Primary # via local mysql.datasource.druid.url = jdbc:mysql://localhost:3306/mysql?useUnicode=true&characterEncoding=utf8&useSSL=false mysql.datasource.druid.username=root mysql.datasource.druid.password=123456 mysql.datasource.druid.driverClassName=com.mysql.jdbc.Driver #监控统计拦截的filters mysql.datasource.druid.filters=stat #配置初始化大小/最小/最大 mysql.datasource.druid.initialSize=1 mysql.datasource.druid.minIdle=1 mysql.datasource.druid.maxActive=20 #获取连接等待超时时间 mysql.datasource.druid.maxWait=60000 #间隔多久进行一次检测,检测需要关闭的空闲连接 mysql.datasource.druid.timeBetweenEvictionRunsMillis=60000 #一个连接在池中最小生存的时间 mysql.datasource.druid.minEvictableIdleTimeMillis=300000 mysql.datasource.druid.validationQuery=SELECT 'x' mysql.datasource.druid.testWhileIdle=true mysql.datasource.druid.testOnBorrow=false mysql.datasource.druid.testOnReturn=false #打开PSCache,并指定每个连接上PSCache的大小。oracle设为true,mysql设为false。分库分表较多推荐设置为false mysql.datasource.druid.poolPreparedStatements=false mysql.datasource.druid.maxPoolPreparedStatementPerConnectionSize=20 ## Oracle 数据源配置,从库 oracle.datasource.druid.url=jdbc:oracle:thin:@(DESCRIPTION =(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=scot))) oracle.datasource.druid.username=root oracle.datasource.druid.password=123456 oracle.datasource.druid.driverClassName=oracle.jdbc.OracleDriver #监控统计拦截的filters oracle.datasource.druid.filters=stat #配置初始化大小/最小/最大 oracle.datasource.druid.initialSize=1 oracle.datasource.druid.minIdle=1 oracle.datasource.druid.maxActive=20 #获取连接等待超时时间 oracle.datasource.druid.maxWait=60000 #间隔多久进行一次检测,检测需要关闭的空闲连接 oracle.datasource.druid.timeBetweenEvictionRunsMillis=60000 #一个连接在池中最小生存的时间 oracle.datasource.druid.minEvictableIdleTimeMillis=300000 oracle.datasource.druid.validationQuery=SELECT 'x' FROM DUAL oracle.datasource.druid.testWhileIdle=true oracle.datasource.druid.testOnBorrow=false oracle.datasource.druid.testOnReturn=false #打开PSCache,并指定每个连接上PSCache的大小。oracle设为true,mysql设为false。分库分表较多推荐设置为false oracle.datasource.druid.poolPreparedStatements=true oracle.datasource.druid.maxPoolPreparedStatementPerConnectionSize=20