Spring定时任务无故停止又不报错的解决

目录
  • Spring定时任务无故停止又不报错
    • 解决方案
  • Spring定时任务跑完不再启动
    • spring的定时任务有以下两个特性
    • 排查方式
    • 解决思路

Spring定时任务无故停止又不报错

一开始是使用Spring自带的定时器来配置定时任务的,简单快捷,配置如下:

<bean id="refreshCache" class="com.gionee.baserom.search.job.RefreshCache" />
<task:scheduled-tasks>
    <task:scheduled ref="refreshCache" method="execute" cron="0 */30 * * * ?"/>
</task:scheduled-tasks>

但是使用一段时间之后就无故停止,且不报错,所以没有相关错误日志,需要重启Tomcat之后才能继续执行定时任务。

开始以为由于数据库最大连接数的限制,设置成翻倍了之后仍出现这问题。在同学的提醒下意识到可能是线程阻塞导致,于是网上查到原因:

Spring定时任务默认都是并发执行的,不会等待上一次任务执行完毕,只要间隔时间到就会执行。

解决方案

1.将JobDetail的concurrent属性配置为false。不允许任务并发执行。

2.任务执行时间较长时,查找根本问题。

于是把Spring自带的定时器改用Quartz,依赖相关包:

<dependency>
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz</artifactId>
        <version>2.2.1</version>
</dependency>

定时任务配置如下:

<!-- 工作的bean -->
    <bean id="myJob" class=" com.gionee.baserom.exchangerate.job.DailyTaskJob" />
    <!-- 定义任务,为了避免线程阻塞,用concurrent=false -->
    <bean id="myJobDetail"
        class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="myJob" />
        <property name="targetMethod" value="execute" />
        <property name="concurrent" value="false" />
    </bean>
    <!-- 配置触发器  -->
    <bean id="myJobTrigger"
        class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="jobDetail" ref="myJobDetail" />
        <property name="cronExpression" value="0 0/30 * * * ?" />
    </bean>
    <!-- 配置调度器 -->
    <bean name="startQuertz" lazy-init="false" autowire="no" destroy-method="destroy"
        class="com.gionee.baserom.exchangerate.util.SchedulerFactoryBeanWithShutdownDelay" >
        <property name="quartzProperties">
            <props>
                <prop key="org.quartz.threadPool.threadCount">1</prop>
            </props>
        </property>
        <property name="waitForJobsToCompleteOnShutdown">
            <value>false</value>
        </property>
        <property name="triggers">
            <list>
                <ref bean="myJobTrigger" />
            </list>
        </property>
    </bean>

在startQuartz中用到SchedulerFactoryBeanWithShutdownDelay是因为当Tomcat被关闭时,有可能导致任务线程并未完全关闭,导致内存泄漏。

SchedulerFactoryBeanWithShutdownDelay.java

import org.quartz.SchedulerException;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
public class SchedulerFactoryBeanWithShutdownDelay extends SchedulerFactoryBean {
    @Override
    public void destroy() throws SchedulerException {
        super.destroy();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

Spring定时任务跑完不再启动

spring的定时任务有以下两个特性

1、单定时任务之间是串行,之前的任务没执行完,下一个任务不会启动。

2、多个任务之间会相互干扰,其他同一时刻启动的任务没执行完,下一个任务不会启动。

排查方式

1、首先检查自己的代码,是否有死锁、卡住、bug、http请求没有设置超时时间等问题。

2、检查是否所有定时任务都不启动,如果是基本判断是特性2导致的,检查是哪个定时任务执行慢、卡住、出现bug等情况。

解决思路

1、修复bug,如果有的话。

2、如果就是有个任务执行慢,无法优化,可以不用spring的定时任务,改用Quartz。

依赖包

<dependency>
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz</artifactId>
        <version>2.2.1</version>
</dependency>

配置:

<!-- 工作的bean -->
    <bean id="myJob" class=" com.gionee.baserom.exchangerate.job.DailyTaskJob" />

    <!-- 定义任务,为了避免线程阻塞,用concurrent=false -->
    <bean id="myJobDetail"
        class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="myJob" />
        <property name="targetMethod" value="execute" />
        <property name="concurrent" value="false" />
    </bean>

    <!-- 配置触发器  -->
    <bean id="myJobTrigger"
        class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="jobDetail" ref="myJobDetail" />
        <property name="cronExpression" value="0 0/30 * * * ?" />
    </bean>

    <!-- 配置调度器 -->
    <bean name="startQuertz" lazy-init="false" autowire="no" destroy-method="destroy"
        class="com.gionee.baserom.exchangerate.util.SchedulerFactoryBeanWithShutdownDelay" >
        <property name="quartzProperties">
            <props>
                <prop key="org.quartz.threadPool.threadCount">1</prop>
            </props>
        </property>
        <property name="waitForJobsToCompleteOnShutdown">
            <value>false</value>
        </property>
        <property name="triggers">
            <list>
                <ref bean="myJobTrigger" />
            </list>
        </property>
    </bean>

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • SpringBoot 定时任务遇到的坑

    前言 springboot已经支持了定时任务Schedule模块,一般情况已经完全能够满足我们的实际需求.今天就记录一下我使用 schedule 时候踩的坑吧. 想要使用定时,我们首先要开启支持,其实就是在启动类上面加个注解就 Ok. @SpringBootApplication @EnableScheduling public class Application { public static void main(String[] args) { SpringApplication.run(A

  • SpringBoot启动自动终止也不报错的原因及解决

    目录 SpringBoot启动自动终止也不报错 原因 解决方案 springboot 启动一段时间之后自动挂掉的解决 解决办法 SpringBoot启动自动终止也不报错 Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled. Disconnected from the target VM, address: '

  • SpringBoot实现动态定时任务

    项目情况: 在当前项目中需要一个定时任务来清除过期的校验码,如果使用数据库存储过程的话不方便维护.因此采用SpringBoot自带的方式来设置定时任务. 技术说明: SpringBoot自带的方式有两种可以实现: 一种是使用@Scheduled注解的方式,只需要在启动类或者它所在的类上添加@EnableScheduling注解允许执行定时任务,并且设置Schecduled注解的参数,诸如: 1.cron是设置定时执行的表达式,如 0 0/5 * * * ?每隔五分钟执行一次 2.zone表示执行

  • springboot schedule 解决定时任务不执行的问题

    @schedule 注解 是springboot 常用的定时任务注解,使用起来简单方便,但是如果定时任务非常多,或者有的任务很耗时,会影响到其他定时任务的执行,因为schedule 默认是单线程的,一个任务在执行时,其他任务是不能执行的.解决办法是重新配置schedule,改为多线程执行.只需要增加下面的配置类就可以了. import org.springframework.boot.autoconfigure.batch.BatchProperties; import org.springfr

  • Spring定时任务无故停止又不报错的解决

    目录 Spring定时任务无故停止又不报错 解决方案 Spring定时任务跑完不再启动 spring的定时任务有以下两个特性 排查方式 解决思路 Spring定时任务无故停止又不报错 一开始是使用Spring自带的定时器来配置定时任务的,简单快捷,配置如下: <bean id="refreshCache" class="com.gionee.baserom.search.job.RefreshCache" /> <task:scheduled-ta

  • spring cloud feign不支持@RequestBody+ RequestMethod.GET报错的解决方法

    1.问题梳理: 异常:org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported 很明显是最终feign执行http请求时把这个方法认定为POST,但feign client中又定义了RequestMethod.GET 或 @GetMapping,冲突导致报错 那么为什么feign会认为这个方法是post呢? 源码追踪: 1.我们从feignClient注解

  • 基于spring boot 日志(logback)报错的解决方式

    记录一次报错解决方法: No converter found capable of converting from type [java.lang.String] to type [java.util.Map<java.lang.String, java.lang.String>] org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'logging.le

  • Spring Boot集成Druid出现异常报错的原因及解决

    Spring Boot集成Druid异常 在Spring Boot集成Druid项目中,发现错误日志中频繁的出现如下错误信息: discard long time none received connection. , jdbcUrl : jdbc:mysql://******?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8, version : 1.2.3, las

  • spring无法引入注解及import org.springframework.web.bind.annotation.*报错的解决

    本文主要介绍了spring无法引入注解及import org.springframework.web.bind.annotation.*报错的解决,具体如下: 如图所示,spring的注解报红,无法引入包,推测是spring-web和spring-webmvc这两个包的问题,去看pom.xml, 显示没有问题 进入maven库,两个包都存在 那么,问题在哪里呢? 扫了一眼project里面的External libraries,发现并没有spring-web和spring-webmvc,尝试手动

  • springboot新建项目pom.xml文件第一行报错的解决

    目录 springboot新建项目pom.xml文件第一行报错 新建一个测试项目 下面是文件 解决这个问题只需要 springboot创建过程中pom.xml报错 问题出现原因 解决办法 springboot新建项目pom.xml文件第一行报错 新建一个测试项目 发现创建完毕pom.xml文件报错,提示 Description Resource Path Location Type Unknown pom.xml /demo line 1 Maven Configuration Problem

  • springboot配置数据库密码特殊字符报错的解决

    目录 配置数据库密码特殊字符报错 解决 yml文件中密码特殊字符引起启动报错 原因有两个 解决办法 配置数据库密码特殊字符报错 一般的springboot项目会有application.yml或者application.properties文件,开发中需要连接数据库时密码可能会有特殊字符,.properties文件不会报错,但是.yml文件会报错. 解决 yml中password对应的值用单引号引住('!@test')就可以了,如下 spring:     datasource:        

  • idea springBoot项目自动注入mapper为空报错的解决方法

    在SpringBoot项目中,如果使用了MyBatis作为持久层框架,使用自动注入时可能会遇到mapper报空指针异常的问题.这是因为在自动注入时,SpringBoot无法正确识别MyBatis的Mapper接口,需要进行一些额外的配置.解决这个问题的方法有两种: 1.在Mapper接口上添加注解在Mapper接口上添加@Mapper注解,告诉SpringBoot这个接口是一个Mapper接口,需要进行代理.示例如下: @Mapper public interface UserMapper {

  • Git发现git push origin master 报错的解决方法

    git push origin master 报错的解决方法,分享给大家,具体如下: 错误提示如下 [root@linux1 php]# git push -u origin master To git@github.com:kangvcar/Results-Systems--PHP.git ! [rejected] master -> master (fetch first) error: failed to push some refs to 'git@github.com:kangvcar

  • VS2017添加EF的MVC控制器报错的解决方法

    VS2017添加EF的MVC控制器报错的解决方法,供大家参考,具体内容如下 1. 错误描述:no database provider has been configured fot this DbContext. 此类错误是上下文的注册造成的.解决方式在DBContext中重写OnConfiguring方法去注入数据库连接. DbContext中: public static string ConnectionString { get; set; } protected override voi

随机推荐