Spring+Quartz叢集環境搭建
阿新 • • 發佈:2020-12-09
所需依賴
<dependencies> <!--核心包--> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>4.1.9.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>4.1.9.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.1.9.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.1.9.RELEASE</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.1.9.RELEASE</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.24</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.1.9.RELEASE</version> </dependency> </dependencies>
配置檔案quartz.properties
#是否用這個配置檔案 預設不使用
#org.quartz.jobStore.useProperties= true
#表的字首名
org.quartz.jobStore.tablePrefix = qrtz_
#是否使用叢集
org.quartz.jobStore.isClustered = true
#檢查時間間隔
org.quartz.jobStore.clusterCheckinInterval =5000
#最大時間間隔
org.quartz.jobStore.misfireThreshold =60000
org.quartz.jobStore.txIsolationLevelReadCommitted= true
#=========================================================================================
#記憶體
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
#代理
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#=========================================================================================
#如果使用叢集,id必須唯一,所以必須自動生成
org.quartz.scheduler.instanceId =AUTO
#排程器名稱
org.quartz.scheduler.instanceName =MY_CLUSTERED_JOB_SCHEDULER
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
#=========================================================================================
# Configure ThreadPool
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
applicationContext.xml 配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--配置掃描的包--> <context:component-scan base-package="com.otc"/> <!--資料庫連線池--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/quartz"/> <property name="username" value="root"/> <property name="password" value="123456"/> </bean> <!--分散式配置--> <!--配置執行緒池--> <bean name="executor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> <property name="corePoolSize" value="15"/> <property name="maxPoolSize" value="25"/> <property name="queueCapacity" value="100"/> </bean> <!--配置事務管理器--> <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!--配置job詳情--> <!--任務一--> <bean name="jobDetail_1" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass" value="com.otc.HelloJob"/> <!--開啟持久化--> <property name="durability" value="true"/> <!--是否覆蓋--> <property name="requestsRecovery" value="false"/> </bean> <!--任務二--> <bean name="jobDetail_2" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass" value="com.otc.HelloJob2"/> <!--開啟持久化--> <property name="durability" value="true"/> <!--是否覆蓋--> <property name="requestsRecovery" value="false"/> </bean> <!--任務三--> <bean name="jobDetail_3" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass" value="com.otc.Test11"/> <!--開啟持久化--> <property name="durability" value="true"/> <!--是否覆蓋--> <property name="requestsRecovery" value="false"/> </bean> <!--配置觸發時間--> <bean id="cronTrigger_1" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail"> <ref bean="jobDetail_1"/> </property> <!-- 每1秒鐘執行一次 --> <property name="cronExpression"> <value>0/1 * * * * ?</value> </property> <property name="timeZone"> <value>GMT+8:00</value> </property> </bean> <bean id="cronTrigger_2" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail"> <ref bean="jobDetail_2"/> </property> <!-- 每5秒鐘執行一次 --> <property name="cronExpression"> <value>0/5 * * * * ?</value> </property> <property name="timeZone"> <value>GMT+8:00</value> </property> </bean> <bean id="cronTrigger_3" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail"> <ref bean="jobDetail_3"/> </property> <!-- 每10秒鐘執行一次 --> <property name="cronExpression"> <value>0/10 * * * * ?</value> </property> <property name="timeZone"> <value>GMT+8:00</value> </property> </bean> <!--定義排程器,並將Trigger註冊到排程器中--> <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <!--配置檔案--> <property name="configLocation" value="classpath:quartz.properties"/> <!--資料來源--> <property name="dataSource" ref="dataSource"/> <!--任務唯一的名稱,將持久化到資料庫--> <property name="schedulerName" value="mavenTest2"/> <!--每臺叢集機器部署應用的時候更新觸發器--> <property name="overwriteExistingJobs" value="true"/> <property name="applicationContextSchedulerContextKey" value="appl"/> <!-- 設定自動啟動 --> <property name="autoStartup" value="true"/> <!--執行緒池--> <property name="taskExecutor" ref="executor"/> <!--事務--> <property name="transactionManager" ref="transactionManager"/> <property name="triggers"> <list> <ref bean="cronTrigger_1"/> <ref bean="cronTrigger_2"/> <ref bean="cronTrigger_3"/> </list> </property> </bean> </beans>
job類 繼承QuartzJobBean或者實現Job介面
public class HelloJob extends QuartzJobBean { @Override protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException { String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); System.out.println("任務 1 當前時間: "+format); } }
測試
public class TestQuartzSpring { public static void main(String[] args) { //工廠啟動,排程器啟動,任務排程開始 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); } }
可以同時啟動多個任務來檢視效果
分散式方式使用資料庫,任務相關的資訊存入到資料庫中,所有的節點連線到同一個資料庫,能夠進行共享資料,實現任務不重複跑不漏跑
其中持久化時:
如果需要使用單個方法設定定時任務,是不能持久化的:
Spring從2.0.2開始便不再支援Quartz。具體表現在Quartz+Spring把Quartz的Task例項化進入資料庫時,會產生:Serializable的錯誤:
Unable to serialize JobDataMap for insertion into database because the value of property 'methodInvoker' is not serializable
所以需要自己定義一個類實現MethodInvoker的邏輯
使用JobDetail的jobClass和JobDataAsMap屬性定義一個類來實現,思路是這樣,但我沒成功.......所以就不放程式碼了