#java #spring #spring-boot #quartz-scheduler
Вопрос:
Мне удалось настроить два задания в моем приложении Spring Boot, как показано ниже.
- Эхо-задание, запланированное на каждые 3 минуты.
@Service
public class TransactServiceImpl {
@Scheduled(fixedRateString = "${interval}")
@Override
public void echo() { /* implementation ommitted*/
}
}
В журналах я вижу "logger":"com.pip.service.impl.TransactServiceImpl", "msg":"Echo", "thread":"scheduling-1"
, и это происходит каждые 3 минуты.
- Я также настроил задание Quartz, запланированное на каждую минуту, которое отлично работает только тогда, когда я комментирую
//@Scheduled
echo
задание. Когда я запускаю их оба вместе, запускается только задание echo. Я полагаю, что это происходит из-за того, что поток, который должен выполнять задание Quartz, каким-то образом блокируется или что-то связано с ThreadPool, я полагаю. Работа с кварцем должна выполняться только один раз ночью, но я сохранил ее как 1 минуту для целей тестирования. Мне нужно, чтобы эти задания работали вместе асинхронно. Вот мои конфигурации кварца.
@Configuration
@EnableAsync
@EnableScheduling
public class SchedulerJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
private AutowireCapableBeanFactory beanFactory;
@Override
public void setApplicationContext(final ApplicationContext context) {
beanFactory = context.getAutowireCapableBeanFactory();
}
@Override
protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
final Object job = super.createJobInstance(bundle);
beanFactory.autowireBean(job);
return job;
}
}
ShedulerConfig
@Configuration
public class SchedulerConfig {
@Autowired
private DataSource dataSource;
@Autowired
private ApplicationContext applicationContext;
@Autowired
private QuartzProperties quartzProperties;
@Bean
public SchedulerFactoryBean schedulerFactoryBean() {
SchedulerJobFactory jobFactory = new SchedulerJobFactory();
jobFactory.setApplicationContext(applicationContext);
Properties properties = new Properties();
properties.putAll(quartzProperties.getProperties());
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setOverwriteExistingJobs(true);
factory.setDataSource(dataSource);
factory.setQuartzProperties(properties);
factory.setJobFactory(jobFactory);
factory.setTriggers(repoTriggerConfig().getObject());
return factory;
}
@Bean
public JobDetailFactoryBean repoJobConfig() {
JobDetailFactoryBean jobDetailFactory = new JobDetailFactoryBean();
jobDetailFactory.setJobClass(RepoJob.class);
jobDetailFactory.setDurability(true);
jobDetailFactory.setGroup("pip-scheduler-group");
return jobDetailFactory;
}
@Bean
public CronTriggerFactoryBean repoTriggerConfig() {
CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();
cronTriggerFactoryBean.setJobDetail(repoJobConfig().getObject());
cronTriggerFactoryBean.setCronExpression("0 0/1 0 ? * * *");
cronTriggerFactoryBean.setGroup("pip-scheduler-group");
return cronTriggerFactoryBean;
}
}
RepoJob
@Slf4j
public class RepoJob implements Job {
@Autowired RepoService repoService;
@Autowired RepoUtil repoUtil;
@Override public void execute(JobExecutionContext jobExecutionContext)
throws JobExecutionException {
boolean success = repoService.createFile();
if (success) {
try {
boolean isSuccess = repoUtil.sendInfo();
if (isSuccess) {
log.info("Info sent success");
}
} catch (Exception ex) {
log.error(ex);
}
}
}
}
quartz properties from application.yml
quartz:
properties:
org.quartz.jobStore.isClustered: true
org.quartz.scheduler.instanceId: AUTO
org.quartz.jobStore.driverDelegateClass: org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
org.quartz.scheduler.instanceName: pip-clustered-scheduler
org.quartz.jobStore.class: org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.useProperties: true
org.quartz.jobStore.misfireThreshold: 60000
org.quartz.jobStore.tablePrefix: qrtz_
org.quartz.plugin.shutdownHook.class: org.quartz.plugins.management.ShutdownHookPlugin
org.quartz.plugin.shutdownHook.cleanShutdown: TRUE
jdbc:
initialize-schema: never
job-store-type: jdbc
Использует ту же схему базы данных для таблиц приложений и кварца. Я не уверен, есть ли что-то неправильное в том, как настроен кварц.
Не мог бы кто-нибудь, пожалуйста, провести меня сюда. Это мой первый раз, когда я использую кварц. Спасибо.
Журнал запуска:
INFO [StartupInfoLogger.java:55] Thread:[main] Starting PipDvsApplication using Java 11.0.11 on B720L with PID 22720 (D:Projectspip-dvs-apptargetclasses started by U55097 in D:Projectspip-dvs-app)
INFO [SpringApplication.java:663] Thread:[main] The following profiles are active: dev
INFO [DirectJDKLog.java:173] Thread:[main] Initializing ProtocolHandler ["http-nio-9090"]
INFO [DirectJDKLog.java:173] Thread:[main] Starting service [Tomcat]
INFO [DirectJDKLog.java:173] Thread:[main] Starting Servlet engine: [Apache Tomcat/9.0.50]
INFO [DirectJDKLog.java:173] Thread:[main] Initializing Spring embedded WebApplicationContext
INFO [HikariDataSource.java:110] Thread:[main] HikariPool-1 - Starting...
INFO [HikariDataSource.java:123] Thread:[main] HikariPool-1 - Start completed.
INFO [IsoClient.java:77] Thread:[main] Connected with host:216.76.27.250 , post:20500, status:false
INFO [StdSchedulerFactory.java:1220] Thread:[main] Using default implementation for ThreadExecutor
INFO [SchedulerSignalerImpl.java:61] Thread:[main] Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
INFO [QuartzScheduler.java:229] Thread:[main] Quartz Scheduler v.2.3.2 created.
INFO [ShutdownHookPlugin.java:120] Thread:[main] Registering Quartz shutdown hook.
INFO [QuartzScheduler.java:294] Thread:[main] Scheduler meta-data: Quartz Scheduler (v2.3.2) 'pip-dvs-clustered-scheduler' with instanceId 'B720L1633520106597'
Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
NOT STARTED.
Currently in standby mode.
Number of jobs executed: 0
Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 20 threads.
Using job-store 'org.springframework.scheduling.quartz.LocalDataSourceJobStore' - which supports persistence. and is clustered.
INFO [StdSchedulerFactory.java:1374] Thread:[main] Quartz scheduler 'pip-dvs-clustered-scheduler' initialized from an externally provided properties instance.
INFO [StdSchedulerFactory.java:1378] Thread:[main] Quartz scheduler version: 2.3.2
INFO [QuartzScheduler.java:2293] Thread:[main] JobFactory set to: com.pip.job.SchedulerJobFactory@b3c7c75
INFO [DirectJDKLog.java:173] Thread:[main] Starting ProtocolHandler ["http-nio-9090"]
INFO [QuartzScheduler.java:547] Thread:[main] Scheduler pip-dvs-clustered-scheduler_$_B720L1633520106597 started.
INFO [StartupInfoLogger.java:61] Thread:[main] Started PipDvsApplication in 58.08 seconds (JVM running for 60.088)
INFO [DirectJDKLog.java:173] Thread:[RMI TCP Connection(2)-192.168.29.216] Initializing Spring DispatcherServlet 'dispatcherServlet'
Комментарии:
1. Сначала вы должны проверить таблицу
qrtz_job_details
таблицы, чтобы узнать, сохраняется ли запись задания quartz в базе данных или нет. это поможет вам определить, правильно ли настроена работа или нет. если есть запись, найдите связанную таблицу триггеровqrtz_corn_triggers
2. @msucil Таблицы обновляются с подробной информацией о запуске приложения. Должен ли я преобразовать
echo
задание в задание quartz, чтобы сделать его частью того же пула потоков quartz? Может быть, я не до конца понимаю, как это работает. Кроме того, должен ли я очищать таблицы quartz при каждом запуске? Теперь приложение запускается с журналами, в которых говоритсяScheduler started
, но затем в журнале не видно никаких дальнейших действий. Пожалуйста, направьте