SpringBoot集成quartz定时任务trigger_state状态ERROR解决办法

在Java项目中使用Quartz进行定时任务调度时遇到问题,某些任务状态异常变为ERROR。经排查,发现由于两个服务实例运行同一数据库导致。老版本服务因找不到相应job类而引发错误。解决方案是检查数据库中的服务进程,更新代码或关闭旧服务,确保代码一致性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

Java项目,使用quartz定时任务,然后出现一个奇怪问题,就是新增job调度的时候,发现有写定时任务状态直接变成ERROR了,或者跑了一两次后变成ERROR了,当时还在纳闷,怎么会这样,查日志,发现代码没有错误,手动执行都是可以的,然后发现有两个服务在跑同一个数据库

quartz定时任务是配置在数据库的.

然后发现一个服务器是很老版本的代码,导致运行时找不到对应的job类,然后状态直接变成ERROR了.关掉其中比较老旧服务就行了. 或者两个服务代码一致.

解决办法

1.查看当前数据库有哪些服务进程调度

sql命令:  show  processlist;

他会显示所有访问你指定数据库的进程的

 然后找到对应服务器,更新代码或者停掉其中一个服务就行了.

### 回答1: Spring Boot是一个轻量级的Java web开发框架,而Quartz是一个用于任务调度的高可靠性、高扩展性的开源工具。将两者整合起来,可以更方便地实现任务调度,本文就介绍一下关于Spring Boot2与Quartz整合的Demo。 该Demo的主要功能包括任务添加、任务修改、任务移除以及任务查看。 首先,我们需要添加Quartz的相关依赖,如下: ```xml <!-- Quartz --> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.2</version> </dependency> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz-jobs</artifactId> <version>2.3.2</version> </dependency> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz-jobs-no-logging</artifactId> <version>2.3.2</version> </dependency> ``` 然后,我们需要配置数据库,以Quartz自带的表为例,可使用以下配置: ```yaml spring: datasource: url: jdbc:mysql://localhost:3306/quartz?useUnicode=true&characterEncoding=utf-8&useSSL=false username: root password: root driver-class-name: com.mysql.jdbc.Driver quartz: scheduler: instanceName: quartzScheduler instanceId: AUTO jobStore: class: org.quartz.impl.jdbcjobstore.JobStoreTX driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate tablePrefix: QRTZ_ isClustered: false threadPool: class: org.quartz.simpl.SimpleThreadPool threadCount: 5 threadPriority: 5 threadsInheritContextClassLoaderOfInitializingThread: true ``` 接下来,我们需要创建一个JobDetail,用于指定需要执行的任务: ```java @Component public class SomeJob extends QuartzJobBean { private String someParam; public void setSomeParam(String someParam) { this.someParam = someParam; } @Override protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException { // 任务执行逻辑 } } ``` 接下来,我们需要使用CronTriggerFactoryBean生成一个CronTrigger: ```java @Component public class CronTriggerJob { @Autowired private Scheduler quartzScheduler; @Autowired private SomeJob someJob; public void start() throws Exception { CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean(); cronTriggerFactoryBean.setJobDetail(getJobDetail()); cronTriggerFactoryBean.setCronExpression("0/5 * * * * ?"); cronTriggerFactoryBean.setName("myCronTrigger"); cronTriggerFactoryBean.afterPropertiesSet(); Trigger trigger = cronTriggerFactoryBean.getObject(); quartzScheduler.scheduleJob(getJobDetail(), trigger); } private JobDetail getJobDetail() { JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean(); jobDetailFactoryBean.setJobClass(SomeJob.class); jobDetailFactoryBean.setName("myJobDetail"); jobDetailFactoryBean.setDescription("this is my job detail"); jobDetailFactoryBean.getJobDataMap().put("jobParam", "job param"); jobDetailFactoryBean.afterPropertiesSet(); return jobDetailFactoryBean.getObject(); } } ``` 接下来,我们需要配置一个定时任务Controller,用于实现定时任务的添加、修改、移除以及查看功能: ```java @RestController public class QuartzController { private static final Logger logger = LoggerFactory.getLogger(QuartzController.class); @Autowired private Scheduler quartzScheduler; /** * 添加定时任务 */ @PostMapping("/addJob") public void addJob(@RequestParam String jobName, @RequestParam String jobGroup, @RequestParam String cronExpression) { try { JobDetail jobDetail = JobBuilder.newJob(SomeJob.class) .withIdentity(jobName, jobGroup) .build(); CronTrigger trigger = TriggerBuilder.newTrigger() .withIdentity(jobName, jobGroup) .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)) .build(); quartzScheduler.scheduleJob(jobDetail, trigger); logger.info("add job success, jobName:{}, jobGroup:{}, cronExpression:{}", jobName, jobGroup, cronExpression); } catch (SchedulerException e) { logger.error("add job error, jobName:{}, jobGroup:{}, cronExpression:{}, e:{}", jobName, jobGroup, cronExpression, e.getMessage(), e); } } /** * 修改定时任务 */ @PostMapping("/modifyJob") public void modifyJob(@RequestParam String jobName, @RequestParam String jobGroup, @RequestParam String cronExpression) { try { TriggerKey triggerKey = new TriggerKey(jobName, jobGroup); CronTrigger oldTrigger = (CronTrigger) quartzScheduler.getTrigger(triggerKey); if (oldTrigger != null) { CronTrigger newTrigger = TriggerBuilder.newTrigger() .withIdentity(jobName, jobGroup) .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)) .startNow() .build(); // 更新定时任务 quartzScheduler.rescheduleJob(triggerKey, newTrigger); logger.info("modify job success, jobName:{}, jobGroup:{}, cronExpression:{}", jobName, jobGroup, cronExpression); } } catch (SchedulerException e) { logger.error("modify job error, jobName:{}, jobGroup:{}, cronExpression:{}, e:{}", jobName, jobGroup, cronExpression, e.getMessage(), e); } } /** * 移除定时任务 */ @PostMapping("/removeJob") public void removeJob(@RequestParam String jobName, @RequestParam String jobGroup) { try { TriggerKey triggerKey = new TriggerKey(jobName, jobGroup); quartzScheduler.unscheduleJob(triggerKey); quartzScheduler.deleteJob(JobKey.jobKey(jobName, jobGroup)); logger.info("remove job success, jobName:{}, jobGroup:{}", jobName, jobGroup); } catch (Exception e) { logger.error("remove job error, jobName:{}, jobGroup:{}, e:{}", jobName, jobGroup, e.getMessage(), e); } } /** * 查看定时任务 */ @GetMapping("/listJob") public List<Map<String, Object>> listJob() { List<Map<String, Object>> list = new ArrayList<>(); try { System.out.println(quartzScheduler.getSchedulerName()); GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup(); Set<JobKey> jobKeys = quartzScheduler.getJobKeys(matcher); for (JobKey jobKey : jobKeys) { List<? extends Trigger> triggers = quartzScheduler.getTriggersOfJob(jobKey); for (Trigger trigger : triggers) { Map<String, Object> item = new HashMap<>(); JobDetail jobDetail = quartzScheduler.getJobDetail(jobKey); item.put("jobName", jobDetail.getKey().getName()); item.put("jobGroup", jobDetail.getKey().getGroup()); item.put("triggerName", trigger.getKey().getName()); item.put("triggerGroup", trigger.getKey().getGroup()); item.put("triggerState", quartzScheduler.getTriggerState(trigger.getKey())); if (trigger instanceof SimpleTrigger) { SimpleTrigger simpleTrigger = (SimpleTrigger) trigger; item.put("startTime", simpleTrigger.getStartTime()); item.put("endTime", simpleTrigger.getEndTime()); } if (trigger instanceof CronTrigger) { CronTrigger cronTrigger = (CronTrigger) trigger; item.put("cronExpression", cronTrigger.getCronExpression()); } list.add(item); } } } catch (SchedulerException e) { logger.error("list job error, e:{}", e.getMessage(), e); } return list; } } ``` 最后,我们需要在启动类上添加@Configuration注解,以确保程序能够正常运行: ```java @SpringBootApplication @Configuration public class QuartzDemoApplication { public static void main(String[] args) { SpringApplication.run(QuartzDemoApplication.class, args); } // 启用Quartz调度器 @Bean public SchedulerFactoryBean schedulerFactoryBean() { SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean(); schedulerFactoryBean.setDataSource(dataSource); schedulerFactoryBean.setAutoStartup(true); schedulerFactoryBean.setWaitForJobsToCompleteOnShutdown(true); schedulerFactoryBean.setQuartzProperties(quartzProperties()); return schedulerFactoryBean; } // 配置Quartz属性 private Properties quartzProperties() { Properties properties = new Properties(); properties.put("org.quartz.scheduler.instanceName", "quartzScheduler"); properties.put("org.quartz.scheduler.instanceId", "AUTO"); properties.put("org.quartz.jobStore.driverDelegateClass", "org.quartz.impl.jdbcjobstore.StdJDBCDelegate"); properties.put("org.quartz.jobStore.dataSource", "quartzDataSource"); properties.put("org.quartz.jobStore.tablePrefix", "QRTZ_"); properties.put("org.quartz.jobStore.isClustered", false); properties.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool"); properties.put("org.quartz.threadPool.threadCount", "5"); properties.put("org.quartz.threadPool.threadPriority", "5"); properties.put("org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread", true); return properties; } } ``` 至此,一款功能完备的Spring Boot2与Quartz整合Demo便完成了。 ### 回答2: 以下是一个使用Spring Boot 2和Quartz整合的简单示例: 首先,确保在你的项目中添加了以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency> ``` 然后,创建一个Quartz配置类,用于配置定时任务的调度器、触发器和任务: ```java @Configuration public class QuartzConfig { @Autowired private ApplicationContext applicationContext; @Bean public JobFactory jobFactory() { AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory(); jobFactory.setApplicationContext(applicationContext); return jobFactory; } @Bean public Scheduler scheduler() throws SchedulerException { SchedulerFactory schedulerFactory = new StdSchedulerFactory(); Scheduler scheduler = schedulerFactory.getScheduler(); scheduler.setJobFactory(jobFactory()); scheduler.start(); return scheduler; } } ``` 接下来,创建一个定时任务的示例类: ```java @Service public class MyJob implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { System.out.println("Hello Quartz!"); } } ``` 然后,创建一个定时任务管理器,用于添加、修改、移除和查找定时任务: ```java @Component public class JobManager { @Autowired private Scheduler scheduler; public void addJob(String jobName, String jobGroup, String cronExpression) throws SchedulerException { JobDetail jobDetail = JobBuilder.newJob(MyJob.class) .withIdentity(jobName, jobGroup) .build(); Trigger trigger = TriggerBuilder.newTrigger() .withIdentity(jobName, jobGroup) .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)) .build(); scheduler.scheduleJob(jobDetail, trigger); } public void updateJob(String jobName, String jobGroup, String cronExpression) throws SchedulerException { TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup); CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); trigger = trigger.getTriggerBuilder() .withIdentity(triggerKey) .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)) .build(); scheduler.rescheduleJob(triggerKey, trigger); } public void deleteJob(String jobName, String jobGroup) throws SchedulerException { JobKey jobKey = JobKey.jobKey(jobName, jobGroup); scheduler.deleteJob(jobKey); } public List<Map<String, Object>> getAllJobs() throws SchedulerException { List<Map<String, Object>> jobList = new ArrayList<>(); for (String groupName : scheduler.getJobGroupNames()) { for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))) { Map<String, Object> job = new HashMap<>(); JobDetail jobDetail = scheduler.getJobDetail(jobKey); job.put("name", jobDetail.getKey().getName()); job.put("group", jobDetail.getKey().getGroup()); Trigger trigger = scheduler.getTriggersOfJob(jobKey).get(0); job.put("cronExpression", trigger instanceof CronTrigger ? ((CronTrigger) trigger).getCronExpression() : "N/A"); jobList.add(job); } } return jobList; } } ``` 最后,创建一个控制器类,用于处理定时任务的添加、修改、移除和查找请求: ```java @RestController public class JobController { @Autowired private JobManager jobManager; @PostMapping("/jobs") public void addJob(@RequestParam String name, @RequestParam String group, @RequestParam String cronExpression) throws SchedulerException { jobManager.addJob(name, group, cronExpression); } @PutMapping("/jobs") public void updateJob(@RequestParam String name, @RequestParam String group, @RequestParam String cronExpression) throws SchedulerException { jobManager.updateJob(name, group, cronExpression); } @DeleteMapping("/jobs") public void deleteJob(@RequestParam String name, @RequestParam String group) throws SchedulerException { jobManager.deleteJob(name, group); } @GetMapping("/jobs") public List<Map<String, Object>> getAllJobs() throws SchedulerException { return jobManager.getAllJobs(); } } ``` 现在,你可以运行应用程序并使用以下API进行定时任务的添加、修改、移除和查找操作: - 添加定时任务:`POST /jobs?name=job1&group=group1&cronExpression=0/10 * * * * ?` - 修改定时任务:`PUT /jobs?name=job1&group=group1&cronExpression=0/30 * * * * ?` - 移除定时任务:`DELETE /jobs?name=job1&group=group1` - 查找所有定时任务:`GET /jobs` 这是一个简单的Spring Boot 2和Quartz整合的示例,可以用于管理定时任务的添加、修改、移除和查找操作。你可以根据自己的需求对代码进行进一步的调整和扩展。 ### 回答3: 下面是一个以Spring Boot 2和Quartz整合的简单示例: 1. 首先,你需要在pom.xml文件中添加以下依赖项来引入Spring Boot和Quartz的库: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency> ``` 2. 创建一个Spring Boot的启动类,并添加`@EnableScheduling`注解,以启用定时任务的调度功能: ```java @SpringBootApplication @EnableScheduling public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } ``` 3. 创建一个定时任务的配置类,使用`@Configuration`注解标记,并注入`SchedulerFactoryBean`来创建Quartz调度器: ```java @Configuration public class QuartzConfig { @Bean public SchedulerFactoryBean schedulerFactoryBean() { SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean(); // 添加其他配置,如数据源设置等 return schedulerFactoryBean; } } ``` 4. 创建一个定时任务类,使用`@Component`注解标记,并使用`@Scheduled`注解指定定时任务的执行时间。同时,你还可以使用`@Async`注解来异步执行任务。 ```java @Component public class MyJob { @Scheduled(cron = "0/5 * * * * ?") // 每隔5秒执行一次 public void doJob() { // 定时任务执行的逻辑代码 } } ``` 现在,你的Spring Boot应用已经整合了Quartz,并且可以添加、修改、移除定时任务了。在控制台中你可以通过查看Quartz的日志来确认定时任务是否正常执行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叫兽-郭老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值