ホームページ > Java > &#&チュートリアル > Springboot のスケジュールされたタスクで発生した問題の解決

Springboot のスケジュールされたタスクで発生した問題の解決

不言
リリース: 2019-03-30 10:34:17
転載
4787 人が閲覧しました

この記事の内容は、Springboot のスケジュールされたタスクで発生する問題の解決に関するものであり、一定の参考価値があります。必要な友人は参照してください。お役に立てば幸いです。

前書き: Springboot を使用してスケジュールされたタスクを統合する場合、スケジュールされたタスクの実行に時間がかかりすぎると、他のスケジュールされたタスクの実行がブロックされることがわかりました。

問題の場所

Springboot のドキュメントを確認し、ログを出力 (現在のスレッド情報を出力) したところ、デフォルトでは Springboot がスケジュールされたタスクの処理に 1 つのスレッドしか使用しないことが問題であることがわかりました。

問題のレビュー

例の Springboot バージョンは 2.1.3.RELEASE であることに注意してください。

キー pom ファイル構成

    <!--继承父项目-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    
    ...省略非关键配置
    
    <!-- 引入依赖-->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
ログイン後にコピー

タイミング タスク

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
 * 定时任务
 * @author RJH
 * create at 2019-03-29
 */
@Component
public class SimpleTask {

    private static Logger logger= LoggerFactory.getLogger(SimpleTask.class);

    /**
     * 执行会超时的任务,定时任务间隔为5000ms(等价于5s)
     */
    @Scheduled(fixedRate = 5000)
    public void overtimeTask(){
        try {
            logger.info("current run by overtimeTask");
            //休眠时间为执行间隔的2倍
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 正常的定时任务
     */
    @Scheduled(fixedRate = 5000)
    public void simpleTask(){
        logger.info("current run by simpleTask");
    }
}
ログイン後にコピー

スタートアップ クラス

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class TaskDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(TaskDemoApplication.class, args);
    }

}
ログイン後にコピー

実行結果

...省略非关键信息
2019-03-29 21:22:38.410  INFO 59731 --- [   scheduling-1] com.rjh.task.SimpleTask                  : current run by simpleTask
2019-03-29 21:22:38.413  INFO 59731 --- [   scheduling-1] com.rjh.task.SimpleTask                  : current run by overtimeTask
2019-03-29 21:22:48.413  INFO 59731 --- [   scheduling-1] com.rjh.task.SimpleTask                  : current run by simpleTask
2019-03-29 21:22:48.414  INFO 59731 --- [   scheduling-1] com.rjh.task.SimpleTask                  : current run by overtimeTask
2019-03-29 21:22:58.418  INFO 59731 --- [   scheduling-1] com.rjh.task.SimpleTask                  : current run by simpleTask
2019-03-29 21:22:58.418  INFO 59731 --- [   scheduling-1] com.rjh.task.SimpleTask                  : current run by overtimeTask
2019-03-29 21:23:08.424  INFO 59731 --- [   scheduling-1] com.rjh.task.SimpleTask                  : current run by simpleTask
2019-03-29 21:23:08.424  INFO 59731 --- [   scheduling-1] com.rjh.task.SimpleTask                  : current run by overtimeTask
2019-03-29 21:23:18.425  INFO 59731 --- [   scheduling-1] com.rjh.task.SimpleTask                  : current run by simpleTask
2019-03-29 21:23:18.426  INFO 59731 --- [   scheduling-1] com.rjh.task.SimpleTask                  : current run by overtimeTask
...
ログイン後にコピー

結果分析

実行結果からわかります:

  1. スケジュールされたタスクが実行されるたびに、scheduling-1このスレッド
  2. runs によって処理されます。通常simpleTaskovertimeTask によってブロックされたため、実行間隔が 10

になりました。後でドキュメントを確認しました。 Springboot の スケジュールされたタスクの実行スレッドのデフォルトの最大数は 1 であることもわかりました。

解決策

使用されているSpringbootのバージョンは2.1.3.RELEASEであるため、この問題を解決するには2つの方法があります

Springboot 構成を使用する

スケジュールされたタスクに使用できるスレッドの数を構成ファイルで構成できます:

## 配置可用线程数为10
spring.task.scheduling.pool.size=10
ログイン後にコピー

スケジュールされたタスクのスレッド プールをカスタマイズする

カスタム スレッドを使用するpool デフォルトのスレッド プールの代わりに

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

/**
 * 定时任务配置类
 * @author RJH
 * create at 2019-03-29
 */
@Configuration
public class ScheduleConfig {

    /**
     * 此处方法名为Bean的名字,方法名无需固定
     * 因为是按TaskScheduler接口自动注入
     * @return
     */
    @Bean
    public TaskScheduler taskScheduler(){
        // Spring提供的定时任务线程池类
        ThreadPoolTaskScheduler taskScheduler=new ThreadPoolTaskScheduler();
        //设定最大可用的线程数目
        taskScheduler.setPoolSize(10);
        return taskScheduler;
    }
}
ログイン後にコピー

この記事はここで終了しました。その他の興味深いコンテンツについては、PHP 中国語 Web サイトの Java Video Tutorial 列に注目してください。

以上がSpringboot のスケジュールされたタスクで発生した問題の解決の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:segmentfault.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート