Scheduling LeaderboardJob - Spring Boot 168 EP 25-1

Scheduling LeaderboardJob – Spring Boot 168 EP 25-1

排行榜排程,使用 @Scheduled 來建立項目,以秒或分為單位,定期執行任務, EP 25-1 增加了範例,並透過 Application 來驗證產出結果。

前言

Leaderboard 排行榜統計玩家資訊,如:徽章,勝負場次,勝點,在遊戲中是一個常見的系統,主要圍繞著的滿足玩家競爭心所帶來的榮耀感,因此多久同步一次資料,就使用排程來實現。

Scheduling LeaderboardJob

檔案目錄

./
   +- build.gradle
       +- src
           +- main
               +- resources
               |   +- application.properties
               +- java
                   +- org
                       +- ruoxue
                           +- spring_boot_168
                               +- job
                               |   +- report
                               |       +- leaderboard
                               |           +- LeaderboardJob.java 

設定

Scheduling Tasks

參考此篇:

application.properties

增加 Scheduling 設定。

scheduling.enable=true

@Scheduled 參數

Param Description
cron 表示式,指定任務在特定時間執行
fixedDelay 表示上一次任務執行完成後多久再次執行,參數型別 long ,單位毫秒
fixedDelayString 與 fixedDelay 一樣功能,參數型別 String
fixedRate 表示按一定的頻率執行任務,參數型別 long ,單位毫秒
fixedRateString 與 fixedRate 一樣功能,參數型別 String
initialDelay 表示延遲多久執行第一次任務,參數型別 long,單位毫秒
initialDelayString 與 initialDelay 一樣功能,參數型別 String
zone 時區,預設為目前時區

Cron 表示式

Cron 是一個字串,是由空格隔開的 6 或 7 個域所組成,每一個域對應一個含義,如:秒 分 時 每月第幾天 月 星期 年,其中年是可選欄位。

 ┌───────────── second (0-59)
 │ ┌───────────── minute (0 - 59)
 │ │ ┌───────────── hour (0 - 23)
 │ │ │ ┌───────────── day of the month (1 - 31)
 │ │ │ │ ┌───────────── month (1 - 12) (or JAN-DEC)
 │ │ │ │ │ ┌───────────── day of the week (0 - 7)
 │ │ │ │ │ │          (0 or 7 is Sunday, or MON-SUN)
 │ │ │ │ │ │
 * * * * * *    
Param Description
, – * / 四個字元,有效範圍為 0-59 的整數
, – * / 四個字元,有效範圍為 0-59 的整數
, – * / 四個字元,有效範圍為 0-23 的整數
每月第幾天 , – * / ? L W C 八個字元,有效範圍為 0-31 的整數
, – * / 四個字元,有效範圍為 1-12 的整數或 JAN-DEC
星期 , – * / ? L C # 八個字元,有效範圍為 1-7 的整數或 SUN-SAT 兩個範圍,1 表示星期天,2 表示星期一, 依次類推
* 表示匹配該域的任意值,比如在秒*,就表示每秒都會觸發事件
? 只能用在每月第幾天和星期兩個域,表示不指定值,當 2 個子表示式其中之一被指定了值以後,為了避免衝突,需要將另一個子表示式的值設為 ?
- 表示範圍,例如在分域使用 5-20 ,表示從 5 分到 20 分鐘每分鐘觸發一次
/ 表示起始時間開始觸發,然後每隔固定時間觸發一次,例如在分域使用5/20,則意味著5分,25分,45分,分別觸發一次
, 表示列出列舉值。例如:在分域使用5,20,則意味著在5和20分時觸發一次
L 表示最後,只能出現在星期和每月第幾天域,如果在星期域使用 1L,意味著在最後的一個星期日觸發
W 表示有效工作日(週一到週五),只能出現在每月第幾日域,系統將在離指定日期的最近的有效工作日觸發事件,W 的最近尋找不會跨過月份
LW 這兩個字元可以連用,表示在某個月最後一個工作日,即最後一個星期五
# 用於確定每個月第幾個星期幾,只能出現在每月第幾天域,例如在 1#3,表示某月的第三個星期日

LeaderboardJob.java

新增檔案。

Scheduling Job Description

使用 @Scheduled 定義排程。
使用 @ConditionalOnProperty 設定開啟或關閉排程。

package org.ruoxue.spring_boot_168.job.report.leaderboard;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
@ConditionalOnProperty(name = "scheduling.enable", havingValue = "true")
public class LeaderboardJob {

	@Scheduled(initialDelay = 3000, fixedRate = 3000)
	public void secondBoard() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");
		log.info("secondBoard: " + sdf.format(new Date()));
		try {
			Thread.sleep(10_000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	@Scheduled(initialDelay = 3000, fixedRate = 60000)
	public void minuteBoard() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");
		log.info("minuteBoard: " + sdf.format(new Date()));
	}
}

測試

Application.main

在主程式點右鍵執行 Run As -> Java Application,查看 console 。

2022-06-23T21:02:15.146+0800 [SCHEDULE-T-2] INFO secondBoard:20 - secondBoard: 2022/06/23 09:02:15
2022-06-23T21:02:15.146+0800 [SCHEDULE-T-1] INFO minuteBoard:31 - minuteBoard: 2022/06/23 09:02:15
2022-06-23T21:02:25.146+0800 [SCHEDULE-T-3] INFO secondBoard:20 - secondBoard: 2022/06/23 09:02:25
2022-06-23T21:02:35.147+0800 [SCHEDULE-T-4] INFO secondBoard:20 - secondBoard: 2022/06/23 09:02:35
2022-06-23T21:02:45.148+0800 [SCHEDULE-T-1] INFO secondBoard:20 - secondBoard: 2022/06/23 09:02:45
2022-06-23T21:02:55.148+0800 [SCHEDULE-T-2] INFO secondBoard:20 - secondBoard: 2022/06/23 09:02:55
2022-06-23T21:03:05.148+0800 [SCHEDULE-T-2] INFO secondBoard:20 - secondBoard: 2022/06/23 09:03:05
2022-06-23T21:03:15.146+0800 [SCHEDULE-T-4] INFO minuteBoard:31 - minuteBoard: 2022/06/23 09:03:15

心得分享

Task Scheduler

增加了參數設定 scheduling.enable ,用來開啟或關閉排程執行,尤其當測試或團隊協作時,常常會多人共同維護專案,同時啟動 Server,此時關閉排程,可以避免發生任務互搶執行的情況。

發佈留言