Rumah  >  Artikel  >  Java  >  Bagaimana untuk melaksanakan beberapa tugas berjadual dalam Spring Boot

Bagaimana untuk melaksanakan beberapa tugas berjadual dalam Spring Boot

Java后端技术全栈
Java后端技术全栈ke hadapan
2023-08-15 16:50:341442semak imbas

Dalam pembangunan sebenar, kami akan lebih kurang menggunakan beberapa senario tugas berjadual Artikel ini akan membincangkan tugas berjadual yang biasa digunakan.

Penyelesaian pelaksanaan tugas berjadual yang biasa digunakan termasuk yang berikut:

  • Pemasa: Ini adalah automatik java Dengan kelas java.util.Timer, kelas ini membolehkan anda menjadualkan java.util.TimerTaskTask. Menggunakan kaedah ini membolehkan program anda dilaksanakan pada frekuensi tertentu, tetapi bukan pada masa yang ditentukan. Umumnya kurang digunakan. Timer:这是java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务。使用这种方式可以让你的程序按照某一个频度执行,但不能在指定时间运行。一般用的较少。
  • ScheduledExecutorService:也jdk自带的一个类;是基于线程池设计的定时任务类,每个调度任务都会分配到线程池中的一个线程去执行,也就是说,任务是并发执行,互不影响。
  • Spring TaskSpring3.0以后自带的task,可以将它看成一个轻量级的Quartz,而且使用起来比Quartz简单许多。
  • Quartz
  • ScheduledExecutorService: juga jdk sejak Kelas yang disertakan dengan; ialah kelas tugasan berjadual berdasarkan reka bentuk kumpulan benang Setiap tugasan yang dijadualkan akan diberikan kepada utas dalam kumpulan utas untuk dilaksanakan dengan kata lain, tugasan dilaksanakan secara serentak dan tidak menjejaskan satu sama lain.
  • Spring TaskTugas yang disertakan dengan Spring 3.0 bolehlah; dianggap sebagai Kuarza ringan dan lebih mudah digunakan daripada Kuarza.
    Quartz: Ini ialah Penjadual yang agak berkuasa boleh membenarkan program anda dilaksanakan pada masa tertentu atau pada frekuensi tertentu, tetapi konfigurasinya agak rumit.
  • Pangkalan data, buat jadual dan simpan ungkapan cron dalam jadual.

nacos, menggunakan konfigurasi teragih untuk melaksanakan konfigurasi dinamik ekspresi cron. . Untuk pengenalan terperinci, sila lihat API:

public class TestTimer {
    public static void main(String[] args) {
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                System.out.println("task  run:"+ new Date());
            }
        };
        Timer timer = new Timer();
        //安排指定的任务在指定的时间开始进行重复的固定延迟执行。这里是每3秒执行一次
        timer.schedule(timerTask,10,3000);
    }
}

Gunakan ScheduledExecutorService

Kaedah ini serupa dengan Pemasa, lihat sahaja demo:

public class TestScheduledExecutorService {
    public static void main(String[] args) {
        ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
        // 参数:1、任务体 2、首次执行的延时时间
        //      3、任务执行间隔 4、间隔时间单位
        service.scheduleAtFixedRate(()->System.out.println("task ScheduledExecutorService "+new Date()), 0, 3, TimeUnit.SECONDS);
    }
}

Gunakan Spring Task

kita boleh gunakan tugasan Spring dengan mudah

anotasi yang sangat elegan untuk melaksanakan tugas berjadual, mula-mula buat projek, import kebergantungan:

<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
  </dependency>
  <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
  </dependency>
</dependencies>

Buat kelas tugas: Bagaimana untuk melaksanakan beberapa tugas berjadual dalam Spring Boot

@Slf4j
@Component
public class ScheduledService {
    @Scheduled(cron = "0/5 * * * * *")
    public void scheduled(){
        log.info("=====>>>>>使用cron  {}",System.currentTimeMillis());
    }
    @Scheduled(fixedRate = 5000)
    public void scheduled1() {
        log.info("=====>>>>>使用fixedRate{}", System.currentTimeMillis());
    }
    @Scheduled(fixedDelay = 5000)
    public void scheduled2() {
        log.info("=====>>>>>fixedDelay{}",System.currentTimeMillis());
    }
}

Gunakan anotasi @EnableScheduling pada kelas utama untuk mendayakan sokongan untuk tugas berjadual, dan kemudian mulakan projek

Anda boleh melihat tiga Semua tugas yang dijadualkan telah dilaksanakan, dan ia dilaksanakan secara bersiri dalam urutan yang sama Jika hanya terdapat satu tugasan yang dijadualkan, ini pastinya tiada masalah Apabila bilangan tugasan yang dijadualkan meningkat, jika satu tugasan tersekat, tugas lain tidak akan dapat dilaksanakan. AsyncConfig

@Configuration
@EnableAsync
public class AsyncConfig {
     /*
    此处成员变量应该使用@Value从配置中读取
     */
    private int corePoolSize = 10;
    private int maxPoolSize = 200;
    private int queueCapacity = 10;
    @Bean
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.initialize();
        return executor;
    }
}

@Configuration:表明该类是一个配置类@EnableAsync:开启异步事件的支持

然后在定时任务的类或者方法上添加@Async

Pelaksanaan berbilang benang

Bagaimana untuk melaksanakan beberapa tugas berjadual dalam Spring BootDalam projek Spring tradisional, kami boleh menambah konfigurasi tugas dalam fail konfigurasi xml Dalam projek Spring Boot, kami biasanya menggunakan kelas konfigurasi konfigurasi untuk menambah konfigurasi, jadi buat AsyncConfig class

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

@Configuration: Menunjukkan bahawa kelas ialah kelas konfigurasi@EnableAsync: Hidupkan sokongan untuk acara tak segerak

Kemudian dalam kelas atau kaedah daripada tugas yang dijadualkan Tambah @Async . Akhir sekali mulakan semula projek, setiap tugas berada dalam urutan yang berbeza.

🎜🎜🎜🎜Konfigurasi masa pelaksanaan🎜🎜Dalam tugasan yang dijadualkan di atas, kami menggunakan anotasi @Scheduled pada kaedah untuk menetapkan masa pelaksanaan tugas dan menggunakan tiga kaedah konfigurasi atribut: 🎜
  1. fixedRate: Tentukan tugas berjadual yang dilaksanakan pada kekerapan tertentu
  2. fixedDelay: Tentukan tugas berjadual yang dilaksanakan pada kekerapan tertentu Perbezaan daripada di atas ialah menukar atribut boleh bekerjasama dengan initialDelay tentukan masa pelaksanaan tugas yang tertangguh.
  3. cron: Konfigurasikan masa pelaksanaan tugas melalui ungkapan

Penjelasan terperinci tentang ungkapan cron

Satu ungkapan cron mempunyai sekurang-kurangnya 6 (mungkin 7) elemen masa yang dipisahkan oleh ruang. Mengikut urutan:

  • saat (0~59)
  • minit (0~59)
  • 3 jam (0~23)
  • minit (0~59)
  • 3 jam (0~23)
  • 4 hari (0~3
    )
  • bulan (0~11)

🎜6 minggu (1~7 1=AHAD atau AHAD, ISNIN, SELASA, RABU, KHAM, JUMAAT, SABTU)🎜🎜🎜🎜Tahun (1970-2099)🎜🎜🎜 Setiap elemen boleh menjadi nilai (seperti 6), selang berterusan (9-12), selang (8-18/4) (/ bermaksud setiap 4 jam), senarai (1, 3, 5) , kad bebas. Memandangkan dua elemen "hari dalam bulan" dan "hari dalam minggu" adalah saling eksklusif, salah satu daripadanya mesti ditetapkan. Contoh konfigurasi: 🎜
  • Dilaksanakan setiap 5 saat: */5* * ?
  • Dilaksanakan setiap 1 minit: 0 /1 ?
  • 0 0 10.14,16 pagi
  • 0 0/30 9-17 ? Setiap setengah jam selama 9 hingga 5 jam bekerja
  • 0 0 12 ? pada pukul 12 tengah hari
  • "0 15 10 ? "Cuci setiap hari pada pukul 10:15 pagi
  • "0 15 10 ?" Dicetuskan setiap hari pada 10:15 AM
  • " 0 15 10 ? 2005" Dicetuskan setiap hari pada 10:15 AM pada tahun 2005
  • " 0
    14
  • ?" Dicetuskan setiap 1 minit sepanjang 59
  • "0 0/5 14 ?" hingga 2:55 ptg dan setiap 5 minit dari 6 ptg hingga 6: 55 ptg
  • "0 0-5 14 ?" 3 RABU" setiap hari Rabu pada bulan Mac pukul 2:10 dan 2:44 petang Pencetus
  • "0 15 10 ? ?" Dicetuskan pada jam 10:15 pagi pada 15hb setiap bulan
  • "0 15 10 L * ?" Dicetuskan pada jam 10:15 pagi pada hari terakhir setiap bulan
  • "0 15 10L" *dicetuskan? pada hari Jumaat terakhir setiap bulan pada pukul 10:15 pagi
  • "0 15 10 ? * 6L 2002-2005" Dicetuskan pada hari Jumaat terakhir setiap bulan pada pukul 10 pagi dari 2002 hingga 2005 :15 pencetus
    "
  • 0 15 10 ? * 6#3" Pencetus pada 10:15 pagi pada hari Jumaat ketiga setiap bulan
  • Sesetengah subungkapan boleh mengandungi beberapa julat atau senarai
  • Contohnya: subungkapan Formula (hari (minggu)) boleh jadilah "ISNIN-JUM", "ISNIN, RABU, JUMAAT", "ISNIN-RABU, SABTU"
  • Aksara "*" mewakili semua nilai yang mungkin Aksara "/" digunakan untuk menentukan kenaikan nilai

    Contohnya: "0/15" dalam subungkapan (minit) bermaksud bermula dari minit 0, setiap 15 minit "3/20" dalam subungkapan (minit) bermakna bermula dari minit ke-3, setiap 20 minit (ia mempunyai maksud yang sama seperti "3, 23, 43")

    Aksara "?" hanya digunakan selama beberapa hari Dua sub-ungkapan (bulan) dan hari (minggu), menunjukkan bahawa tiada nilai dinyatakan Apabila salah satu daripada dua subungkapan diberikan nilai, untuk mengelakkan konflik, nilai subungkapan yang lain perlu ditetapkan kepada "?"

    Watak "L" hanya digunakan untuk hari (bulan) dan hari (minggu ) ) dua subungkapan, yang merupakan singkatan untuk perkataan "terakhir" Jika ada sesuatu yang khusus sebelum "L", ia mempunyai makna lain.

    Contohnya: "6L" bermaksud hari ke-6 hingga akhir bulan ini Nota: Apabila menggunakan parameter "L", jangan nyatakan senarai atau julat kerana ini akan menyebabkan masalah

    Watak W mewakili hari bekerja (Isnin-Jumaat) dan hanya boleh digunakan dalam domain hari. Ia digunakan untuk menentukan hari minggu yang paling hampir dengan tarikh yang ditentukan. Kebanyakan pemprosesan perniagaan adalah berdasarkan minggu kerja, jadi watak W boleh menjadi sangat penting.

    Sebagai contoh, 15W dalam medan hari bermaksud "hari minggu yang paling hampir dengan 15 haribulan jika 15 hari Sabtu, maka pencetus akan dicetuskan pada 14 (Jumaat), kerana hari Khamis lebih dekat dengan hari." 15hb daripada Isnin.

    C: bermaksud "Kalendar". Ia bermaksud tarikh yang dikaitkan dengan jadual, atau semua tarikh dalam kalendar jika tarikh itu tidak dikaitkan.

    Sebagai contoh, 5C dalam medan tarikh adalah bersamaan dengan hari pertama selepas hari ke-5 dalam kalendar. 1C dalam medan hari minggu sepadan dengan hari pertama selepas Ahad.

    field allowed Values ​​ watak -watak khas
    Seconds 0 ~ 59 , - * /
    mins 0 ~ 59 , - * + . /

    在线cron表达式生成:http://qqe2.com/cron/index

    整合Quartz

    • 添加依赖

    如果Spring Boot版本是2.0.0以后的,则在spring-boot-starter中已经包含了quart的依赖,则可以直接使用spring-boot-starter-quartz依赖:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-quartz</artifactId>
    </dependency>

    如果是1.5.9则要使用以下添加依赖:

    <dependency>
      <groupId>org.quartz-scheduler</groupId>
      <artifactId>quartz</artifactId>
      <version>2.3.0</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
    </dependency>

    这里我使用Spring Boot版本是2.0.0.BUILD-SNAPSHOT ,该版本开始集成了Quartz,所以事实现起来很方便。其它好像比较麻烦,这里就不介绍,以后有时间再详细深入了解Quartz。

    • 创建任务类TestQuartz,该类主要是继承了QuartzJobBean
    public class TestQuartz extends QuartzJobBean {
        /**
         * 执行定时任务
         * @param jobExecutionContext
         * @throws JobExecutionException
         */
        @Override
        protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
            System.out.println("quartz task "+new Date());
        }
    }
    • 创建配置类QuartzConfig
    @Configuration
    public class QuartzConfig {
        @Bean
        public JobDetail teatQuartzDetail(){
            return JobBuilder.newJob(TestQuartz.class).withIdentity("testQuartz").storeDurably().build();
        }
    
        @Bean
        public Trigger testQuartzTrigger(){
            SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
                    .withIntervalInSeconds(10)  //设置时间周期单位秒
                    .repeatForever();
            return TriggerBuilder.newTrigger().forJob(teatQuartzDetail())
                    .withIdentity("testQuartz")
                    .withSchedule(scheduleBuilder)
                    .build();
        }
    }
    • 启动项目

    Bagaimana untuk melaksanakan beberapa tugas berjadual dalam Spring Boot

    最后

    上面都是简单的介绍了关于Spring Boot定时任务的处理,直接使用SpringTask注解的方式应该是最方便的,而使用Quartz从2.0开始也变得很方便。对于这两种方式,应该说各有长处吧,按需选择。

Atas ialah kandungan terperinci Bagaimana untuk melaksanakan beberapa tugas berjadual dalam Spring Boot. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:Java后端技术全栈. Jika ada pelanggaran, sila hubungi admin@php.cn Padam