java項目定時任務實現

首先配置spring-context.xml文件java

在xmlns 下加以下代碼spring

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());
    }

}

以上定時任務完成。spa

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

網上找了如下四種方法,能夠做爲參考。code

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

二、若是有可能,將定時任務獨立出來,成爲一個單獨的項目工程,單一部署。xml

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

爲ture時候,下一個任務不容許執行。須要注意的是,必定要在finally中加上running = false,要否則任務異常的話,下一次任務永遠不會再執行了。
四、在數據庫建一個表: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,並執行業務邏輯。
相關文章
相關標籤/搜索