我们最近推出了一个新的Java / Spring / Quartz / MyBatis堆栈来处理我们的大型数据密集型作业。它大部分都运作良好,但我们注意到一些有趣的东西。
我们有一对类似的工作,每天运行一次,相隔半小时。每个都执行相同的业务逻辑,在我们的数据库中执行其自己谨慎的用户类型。自从我们将它们发布到生产(大约一周左右)之后,这些工作每天都成功运行。但是在两个不同的场合,我们的日志显示触发器已按时启动,但实际工作直到15分钟才执行。一旦它成为表现出这种行为的第一个触发器/作业,一旦它成为第二个触发器/作业。
我们的日志由GlobalTriggerListener和GlobalJobListener写出,并且由作业本身执行的业务逻辑定期写出,它们都表明,在那些日子里,作业在触发器触发后15分钟运行。没有迹象表明在那段时间内发生任何错误。
以下是我们的spring / quartz上下文XML文件:
<bean name="AnnualXXXRenewals" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.aaa.cron.base.TaskFactory" />
<property name="jobDataAsMap">
<map>
<entry key="taskClassName" value="com.aaa.cron.tasks.AnnualRenewalTask" />
<entry key="arg.mode" value="xxx" />
</map>
</property>
</bean>
<bean name="AnnualYYYRenewals" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.aaa.cron.base.TaskFactory" />
<property name="jobDataAsMap">
<map>
<entry key="taskClassName" value="com.aaa.cron.tasks.AnnualRenewalTask" />
<entry key="arg.mode" value="yyy" />
</map>
</property>
</bean>
<!-- Daily Trigger 8 PM PST (3AM GMT)-->
<bean id="dailyTrigger0800PM" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="AnnualXXXRenewals"/>
<property name="cronExpression" value="0 0 13 ? * * *"/>
</bean>
<!-- Daily Trigger 8:30 PM PST (3:30AM GMT)-->
<bean id="dailyTrigger0830PM" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="AnnualYYYRenewals"/>
<property name="cronExpression" value="0 30 13 ? * * *"/>
</bean>
<bean id="schedulerFactory"
class="com.aaa.wrapper.spring.UpdatingSchedulerFactoryBean"
lazy-init="false">
<property name="configLocation"
value="classpath:com/aaa/config/quartz.properties" />
<property name="autoStartup" value="true" />
<property name="applicationContextSchedulerContextKey" value="applicationContext" />
<property name="overwriteExistingJobs" value="true" />
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="jobFactory">
<bean class="com.aaa.wrapper.spring.AutowiringSpringBeanJobFactory" />
</property>
<property name="jobDetails">
<list>
<ref bean="AnnualXXXRenewals" />
<ref bean="AnnualYYYRenewals" />
</list>
</property>
<property name="triggers">
<list>
<ref bean="dailyTrigger0800PM" />
<ref bean="dailyTrigger0830PM" />
</list>
</property>
</bean>
以下是来自我们的quartz.properties:
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.scheduler.skipUpdateCheck = true
#org.quartz.jobStore.useProperties=true
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = true
# Vendor-specific; MySql uses StdJDBCDelegate
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
# Needed to manage cluster instances
org.quartz.scheduler.instanceId=AUTO
org.quartz.scheduler.instanceName=AAA_SCHEDULER
org.quartz.scheduler.jmx.export=true
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 2
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
# Job and Trigger Listener
org.quartz.jobListener.GlobalJobListener.class = com.aaa.cron.base.GlobalJobListener
org.quartz.jobListener.GlobalJobListener.name = GlobalJobListener
org.quartz.triggerListener.GlobalTriggerListener.class = com.aaa.cron.base.GlobalTriggerListener
org.quartz.triggerListener.GlobalTriggerListener.name = GlobalTriggerListener
其他信息:我们的服务器设置为UTC时间。这些工作一直需要几秒钟才能完成。作业是群集的,目前跨5个Tomcat实例。
有没有人遇到过这样的事情?到目前为止,它没有引起任何问题,但最好弄清楚发生了什么。