`
jandyfish
  • 浏览: 15911 次
社区版块
存档分类
最新评论

spring的cron定时任务解析

阅读更多
在用spring定时任务时,配置如下:
<task:executor id="executor" pool-size="5" />
	<task:scheduler id="scheduler" pool-size="10" />
	<task:annotation-driven executor="executor" scheduler="scheduler" />


配置项schema为spring-task-3.0.xsd。
对某方法定义cron如下:
@Scheduled(cron = "0 */5 * * * ?")
	pulic void run(){
		//other codes…
}

因run方法是每5分钟跑一次,而run方法中具有复杂的业务逻辑(大概包括调用第三方httpservice,导数据到内存计算,再分次批量写库)。Task可能会运行超过5分钟,此种情况下,预期目标是和linux cron一样,定点执行task,而不用理会前一个task是否已完成。

运行一段时间后,发现少了几个点的数据,然后针对数据查看了相应的日志,发现每次都只会有一个shedule线程跑同一个run方法,而这个run方法处于wait状态或5分钟内没跑完,会导致后续的task不能按时启动。

查看spring源码,shedule流程初始化如下:
1.在bean初始化后,通过反射机制,对实例化的bean的class进行注解扫描,判断bean的class定义中@Scheduled注解。若有则判断调度模式,如本题中为cron调度模式。此实现代码位于:
ScheduledAnnotationBeanPostProcessor.postProcessAfterInitialization
在扫描到@Scheduled的方法后,把每一个目标method封装为Runnable,代码如下:
MethodInvokingRunnable runnable = new MethodInvokingRunnable();
					runnable.setTargetObject(bean);
					runnable.setTargetMethod(method.getName());
					runnable.setArguments(new Object[0]);
					try {
						runnable.prepare();
					}
					catch (Exception ex) {
						throw new IllegalStateException("failed to prepare task", ex);
					}


此postProcessAfterInitialization是维护crontasks,fixedRateTasks容器,针对每一个目标method生成相应的MethodInvokingRunnable对实例。

2.针对cron任务,对每一个MethodInvokingRunnable注册相应的CronTrigger,并通过ConcurrentTaskSchedule.shedule创建ReschedulingRunnable执行器并解析cron表达式添加第1个task。
代码实现在ScheduledTaskRegistrar. afterPropertiesSet。

3. ReschedulingRunnable自身 串联schdule。如下代码所示:
public ScheduledFuture schedule() {
		synchronized (this.triggerContextMonitor) {
			this.scheduledExecutionTime = this.trigger.nextExecutionTime(this.triggerContext);
			if (this.scheduledExecutionTime == null) {
				return null;
			}
			long initialDelay = this.scheduledExecutionTime.getTime() - System.currentTimeMillis();
			this.currentFuture = this.executor.schedule(this, initialDelay, TimeUnit.MILLISECONDS);
			return this;
		}
	}

	@Override
	public void run() {
		Date actualExecutionTime = new Date();
		super.run();
		Date completionTime = new Date();
		synchronized (this.triggerContextMonitor) {
			this.triggerContext.update(this.scheduledExecutionTime, actualExecutionTime, completionTime);
		}
		if (!this.currentFuture.isCancelled()) {
			schedule();
		}
	}


其中trigger.nextExecutionTime即获取下一个task的执行时间,并提交到executor执行器。

而见run中,是执行了当前的task后再根据corn表达式获取下一个时间点。如此若当前task超过5分钟则下一个5分钟时间点的任务不会被执行。而想要达到linux cron形式的task调度,则需要在此基础之上进行简单处理。
处理办法:
额外创建一个线程池executor如名称为A,在cron方法中提交runnable给这个A执行。
这样的情况可以满足和linux cron一样的定时需求,但得对task有独立性要求。若前后有存在依赖,或者可能导致数据一致性问题还是得慎重。

ps:依据spring中根据bean来解析相应class的schedule注解,如果相应class的实例为多个,就会导致同时有多个相同的task执行。
分享到:
评论

相关推荐

    定时任务cron 解析为中文.docx

    《定时任务cron解析为中文》 在IT领域,特别是在服务器管理和自动化运维中,定时任务扮演着重要的角色。其中,cron表达式是Unix/Linux系统以及许多其他支持cron的平台用来定义定时任务的一种强大工具。然而,由于其...

    Java 写的Cron表达式解析

    Java中的Cron表达式解析是Java开发者经常遇到的一项任务,特别是在构建定时任务或者调度系统时。Cron表达式源自Unix的crontab命令,用于设置周期性被执行的任务。它使用一组字符串来描述时间序列,包括秒、分钟、...

    spring定时任务所需jar

    例如,Quartz是一个强大的作业调度框架,可以创建复杂的定时任务计划,而CronUtils则是一个现代的,易于使用的Java库,用于解析和生成Cron表达式。 最后,如果项目中使用了Spring Boot,那么`spring-boot-starter-...

    spring2.5 定时器任务

    本文将详细介绍Spring2.5中的定时器任务配置方法,并通过示例代码进行深入解析。 #### 二、定时任务的核心组件介绍 在Spring2.5中,定时任务主要依赖以下几个核心组件: 1. **`ThreadPoolTaskExecutor`**:这是...

    定时任务cron表达式生成.rar

    Spring框架则通过`@Scheduled(cron = "cron表达式")`,将方法标记为定时任务,根据给定的cron表达式自动执行。 使用这个“定时任务cron表达式生成”工具,用户可以直观地设置任务的执行频率,而无需手动编写复杂的...

    Cron表达式解析 翻译为中英文.zip

    Cron表达式是Unix/Linux系统中的定时任务调度器Cron所使用的语法,也被广泛应用于Java世界,例如Quartz、Spring等框架。它允许用户以字符串的形式定义任务的执行时间,如分钟、小时、日期等。这个压缩包文件包含了对...

    spring中定时任务管理.docx

    在Spring中,定时任务支持多种调度规则,包括`cron`、`zone`、`fixedDelay`、`fixedDelayString`、`fixedRate`、`initialDelay`和`initialDelayString`。其中,`cron`表达式是一种强大的工具,用于定义复杂的定时...

    使用Spring Task开发定时任务的Demo

    这个功能强大的工具使得开发者无需依赖外部任务调度库(如Quartz或Cron),就能在Spring环境中轻松实现定时任务。 ### 1. Spring Task基础 Spring Task提供了两种主要的方式来创建定时任务:`@Scheduled`注解和`...

    Spring集成Quartz定时任务框架介绍和Cron表达式详解

    本文将深入探讨如何在Spring项目中集成Quartz,并详细解析Cron表达式,以便更好地理解和运用定时任务。 首先,集成Quartz到Spring项目中通常涉及以下步骤: 1. **引入依赖**:在项目的pom.xml或build.gradle文件中...

    Spring 定时任务

    ### Spring 定时任务 在Spring框架中,定时任务是一个非常重要的特性,它允许开发者以简单的方式实现周期性任务的调度。Spring通过`@Scheduled`注解提供了对定时任务的支持,该注解可以轻松地应用于任何Java方法上...

    web页面可配置话的动态生成spring定时任务,持续到化数据库

    本项目将Spring与Quartz相结合,实现了一个Web页面可配置的动态生成Spring定时任务的功能,并能持久化这些任务到数据库中,这在实际业务场景中非常实用。 首先,我们要理解Spring的定时任务是如何工作的。Spring...

    spring_quartz_定时任务

    Spring通过`@Scheduled`注解提供了一种声明式的方式来创建定时任务,开发者可以在方法上添加此注解,设置定时规则,如cron表达式,来定义任务的执行时间。Spring容器会自动管理这些任务,确保它们在合适的时间被调用...

    Spring Boot定时任务的使用实例代码

    在Spring Boot框架中,定时任务的实现主要依赖于Spring的`@EnableScheduling`注解和`@Scheduled`注解。这两个注解使得开发者能够方便地在Spring Boot应用中创建和管理周期性的任务。以下是对这两个核心概念的详细...

    spring多个定时任务quartz配置 easy518网址导航

    根据提供的信息,我们可以详细解析如何在Spring框架中配置多个基于Quartz的定时任务。Quartz是一个功能强大的开源作业调度库,它可以被应用到Java应用程序中实现复杂调度的需求。本篇文章将深入探讨如何在Spring环境...

    java定时任务代码-spring管理.txt

    根据提供的文件信息,本文将详细解析Java定时任务与Spring框架集成的相关知识点,包括如何在Spring环境中配置和管理定时任务。 ### Java定时任务简介 在Java中实现定时任务主要有以下几种方式: 1. **Timer和...

    spring多个定时任务quartz配置.md

    ### Spring 多个定时任务 Quartz 配置详解 ...通过以上解析,可以看出 Spring 与 Quartz 结合能够方便地实现多个定时任务的配置与管理。通过灵活的 Cron 表达式,可以精确控制任务的执行时间,满足各种业务需求。

    spring定时任务(scheduler)的串行、并行执行实现解析

    Spring定时任务(Scheduler)的串行、并行执行实现解析 Spring Framework提供了一个强大的任务调度器(Scheduler),可以用于实现各种类型的定时任务。其中,串行执行和并行执行是两种常见的任务执行模式。本文将...

    spring动态定时器封装

    Spring与Quartz的整合使得我们可以利用Spring的依赖注入(DI)和AOP(面向切面编程)特性来更好地管理定时任务。 下面,我们来看看如何在Spring中封装动态定时器: 1. **引入依赖**:首先,在项目中引入Quartz和...

    quarzt定时调度任务解析

    4. **配置Trigger**:创建`CronTriggerFactoryBean`,配置JobDetail和cron表达式,cron表达式决定了任务的执行频率。 5. **配置Scheduler**:最后,配置`SchedulerFactoryBean`,并将Trigger注入到其中,这样当调度...

    SSH+quartz实现的可动态配置时间规则的定时任务

    在SSH项目中,Struts负责接收用户的请求,解析并转发到对应的业务逻辑,例如动态配置定时任务的规则,或者启动、停止定时任务的操作。 3. **Hibernate框架**:Hibernate是Java中的一个持久化框架,用于简化数据库...

Global site tag (gtag.js) - Google Analytics