spring和springboot定时任务线程池配置

spring和springboot定时任务线程池配置

1 背景

项目有几个新增的月末报表生成定时任务(使用spring内置的TaskScheduler),相关业务人员反馈报表没有及时生成,让我比较疑惑:虽然生成比较耗时,但是我凌晨就开始跑任务了,怎么能到了中午还没有数据呢?经检查,发现项目没有给定时任务配置定时任务线程池,导致所有的定时任务异步进行,好几个定时任务排队等待启动。一个任务按一小时算,累计下来所有任务跑完花了好几个小时,导致排在后面的定时任务没有按时启动,也没有及时生成文件。所以需要给定时任务配置线程池。

2 配置

2.1 命名空间配置

因为我的项目还在使用spring,所以使用xml命名空间的方式去进行配置。在xml中可以配置打开@Scheduled注解的支持,以及配置定时任务线程池的名称、大小。首先新建一个xml文件,我这里命名为spring-task.xml,然后写入如下代码:

xml配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:task="http://www.springframework.org/schema/task"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd">

    <!--开启注解支持-->
    <task:annotation-driven scheduler="nagiumi-namespace-scheduler"/>
    <!--定时任务线程池配置-->
    <task:scheduler id="nagiumi-namespace-scheduler" pool-size="2"/>
</beans>

我这里就配置了一个大小为2的线程池,名称为nagiumi-namespace-scheduler。接下来写两个测试用的定时任务,其中一个每秒打印一次内容,另一个每5秒打印一次内容并阻塞4秒。如果定时任务仍然是异步的,那么前者就会受到后者阻塞的影响。如果线程池配置生效则不会受到影响。记得将spring-task.xml配置文件用@ImportResource注解导入或者配置contextConfigLocation路径来使配置生效。

测试任务

@Component
public class ScheduleTest {

    @Scheduled(cron = "* * * * * ?")
    public void run1() {
        System.out.println(Thread.currentThread().getName() + "------run1···" + new Date());
    }

    @Scheduled(cron = "0/5 * * * * ?")
    public void run2() throws InterruptedException {
        System.out.println(Thread.currentThread().getName() + "------run2···" + new Date());
        Thread.sleep(4000);
    }
}

输出结果

nagiumi-namespace-scheduler-1------run1···Thu Nov 23 15:13:38 CST 2023
nagiumi-namespace-scheduler-1------run1···Thu Nov 23 15:13:39 CST 2023
nagiumi-namespace-scheduler-1------run1···Thu Nov 23 15:13:40 CST 2023
nagiumi-namespace-scheduler-2------run2···Thu Nov 23 15:13:40 CST 2023
nagiumi-namespace-scheduler-1------run1···Thu Nov 23 15:13:41 CST 2023
nagiumi-namespace-scheduler-1------run1···Thu Nov 23 15:13:42 CST 2023

可以看出来两个定时任务没有互相干扰,利用两个线程实现了同步执行。

2.2 yaml配置

毕竟现在springboot比spring更加主流,我自己也在尽量多熟悉springboot的开发风格,所以也简单了解了一下yaml配置方式。这次直接在默认的application.yml中进行配置:

yaml配置

spring:
  task:
    scheduling:
      pool:
        size: 2
      thread-name-prefix: nagiumi-yaml-scheduler-

springboot也可以继续使用xml配置,用@ImportResource注解将配置文件导入启动类即可。

配置的内容和之前等效。测试代码同上。springboot想要启动注解支持,在启动类上添加@EnableScheduling即可。

输出结果

nagiumi-yaml-scheduler-1------run1···Thu Nov 23 15:42:54 CST 2023
nagiumi-yaml-scheduler-2------run2···Thu Nov 23 15:42:55 CST 2023
nagiumi-yaml-scheduler-1------run1···Thu Nov 23 15:42:55 CST 2023
nagiumi-yaml-scheduler-1------run1···Thu Nov 23 15:42:56 CST 2023
nagiumi-yaml-scheduler-1------run1···Thu Nov 23 15:42:57 CST 2023
nagiumi-yaml-scheduler-1------run1···Thu Nov 23 15:42:58 CST 2023

测试结果没有问题,实现了同步执行。

3 参考文档

https://springdoc.cn/spring/integration.html#scheduling

posted @ 2023-11-23 16:00  pjgyr  阅读(869)  评论(0)    收藏  举报