java項目定時任務實現


首先配置spring-context.xml文件

在xmlns 下加如下代碼

xmlns:task="http://www.springframework.org/schema/task"

在xsi:schemaLocation里添加如下代碼

http://www.springframework.org/schema/task 
http://www.springframework.org/schema/task/spring-task-3.1.xsd

還有任務掃描

<task:annotation-driven />

以上配置完成,新建java類寫定時任務

package com.test.job;

import java.util.Date;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import lombok.extern.log4j.Log4j2;

/**
 * 定時任務測試
 * @author ljl
 *
 */
@Log4j2
@Component
public class TestJob {
    
    @Scheduled(cron = "0 */5 * * * ?")
    public void test1() {
        log.info("每5分鍾執行一次"+ new Date());
    }
    
    @Scheduled(cron = "0 0 12 * * ?")
    private void test2() {
        log.info("每天中午12點執行"+ new Date());
    }

}

以上定時任務完成。

思考:如果多台服務器部署同一個項目,就會出現一個定時任務多次執行的問題,如何解決?

網上找了以下四種方法,可以作為參考。

1、設置執行定時任務的機器名,在代碼中判斷,只讓某一台機器執行。

2、如果有可能,將定時任務獨立出來,成為一個單獨的項目工程,單一部署。

3、將任務的定時觸發模塊、任務的執行模塊分離。任務的定時觸發模塊每台機器都允許觸發任務,但是任務的執行模塊,只要收到一個執行任務,那么下一個執行任務就被忽略掉。任務開始執行設置running = true,任務執行完畢設置running = false,當running

為ture時候,下一個任務不允許執行。需要注意的是,一定要在finally中加上running = false,要不然任務異常的話,下一次任務永遠不會再執行了。
4、在數據庫建一個表:timerT,表里面有三個字段:status(表當前定時器是否處於可運行狀態)、timestamp(時間戳)、serverIP(正在運行定時器的服務器IP)。當兩台服務器,都運行起來后,服務器A開始執行定時器,這時,A會去讀取表timerT的status字段,當為0時,則執行定時器的業務邏輯,此時A定時器,需要把status改為1,以便讓另一台服務器的定時器B不去執行業務邏輯並把當前服務器的IP記錄到表中,同時修改啟動一個新的線程,在XXX長的時間間隔內不斷去修改timestamp的值,當A執行完業務邏輯時,就把status的值改為0,這樣B定時器就可以執行。這樣做可以解決一個問題,就是:當其中一個定時器A掛掉后,我們另一個定時器B,可以比對timestap的值與當前時間是否超過XXX時長,如果超過,則證明定時器A已經掛掉,這時B就會把status的值改成1,把serverIP改成B定時器所在的服務器IP,並執行業務邏輯。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM