欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

spring調度注解@Scheduled方式(含分布式)

 更新時間:2024年11月20日 17:19:25   作者:sjzwangxufeng  
文章介紹了Java中任務調度的幾種常見方法,包括JDK原生的Timer、ScheduledThreadPoolExecutor和Spring的@Scheduled注解,文章還討論了如何在分布式環(huán)境中實現(xiàn)任務調度,并介紹了一些開源的分布式任務調度解決方案,如Quartz和XXL-JOB

簡述

任務調度就是在給定的時間或固定頻率,執(zhí)行業(yè)務邏輯,是比較常見的功能需求。

解決方案有jdk原生的Timer、ScheduledThreadPoolExecutor等,這些類常適用于一些內嵌的業(yè)務邏輯場景。

本文主要介紹注解@Scheduled,以上都是單進程解決方案,經過適當改造,也可以適用于分布式場景,可以滿足大多數(shù)調度業(yè)務場景,具體實現(xiàn)思路下面會做簡單敘述。

配置

開啟

項目開啟調度功能,需要先添加注解@EnableScheduling,否則調度注解@Scheduled就不起作用。

線程池

既然是任務運行,就會涉及線程處理,如果有不同類型的任務,也會出現(xiàn)并行處理,對線程的合理管理,就離不開線程池,以下是線程池配置整理

(1) 不配置(默認)

如果不做任何配置處理,spring-boot 會默認自動構建一個ThreadPoolTaskScheduler線程池類bean, 來管理這些運行任務的線程,默認線程池的具體參數(shù)值,可參考TaskSchedulingProperties類定義的默認值,如下:

// pool
private int size = 1;

// thread
private String threadNamePrefix = "scheduling-";

通過源碼知道,這個默認線程池,內部實際由jdk的ScheduledThreadPoolExecutor類處理,該類采用無限容量隊列,這也就限制了它的最大線程數(shù)不會超過1個,如果有耗時的并行任務,就不能滿足要求,通常情況下,需要根據(jù)業(yè)務場景重新配置這些參數(shù)。

(2) spring配置

spring-boot項目已提供TaskSchedulingAutoConfiguration類,由它自動加載線程池配置參數(shù),并構建ThreadPoolTaskScheduler線程池類bean,以下是約定的配置項:

spring:
  task:
    scheduling:
      threadNamePrefix: my-scheduler-task-
      pool:
        size: 3

線程池的大小,依據(jù)配置調度注解@Scheduled任務的數(shù)量,原則上有幾種任務就需要幾個線程,否則就會出現(xiàn)相互影響,長耗時任務占用線程,導致短耗時任務不能正常運行。

(3) java代碼配置

調度任務不像@Async異常處理,它只有一個線程池,一般情況不用這種配置方式,以下是簡單例子。

@Configuration
public class ScheduleConfig {
	
    private static final String THREAD_NAME_PREFIX = "my-scheduler-task-";	

    @Bean("myTaskScheduler")
    public ThreadPoolTaskScheduler getThreadPoolTaskScheduler() {
    	ThreadPoolTaskScheduler result = new ThreadPoolTaskScheduler();
    	result.setThreadNamePrefix(THREAD_NAME_PREFIX);
    	result.setPoolSize(3);
    	return result;
    }
}

調度規(guī)則

@Scheduled包含參數(shù):

  • cron:定時任務,按cron表達式規(guī)則,定時運行任務,例如,每5分鐘運行一次: 0/5 * * * * ?
  • fixedDelay:按固定間隔執(zhí)行,就是兩個相鄰任務,前一個任務結束到下一個任務開始的間隔時間,單位: 毫秒。
  • fixedRate:按固定頻率執(zhí)行任務,單位: 毫秒。
  • initialDelay:系統(tǒng)啟動后,延時多長時間運行第一次任務,單位: 毫秒。

其中:cron, fixedDelay, fixedRate 配置參數(shù),只能三選一。

分布式

現(xiàn)在系統(tǒng)大多在分布式環(huán)境部署,就需要考慮多實例部署如何協(xié)調執(zhí)行任務問題,以下是常見的解決方案,以及個人的思考。

第三方

目前第三方的開源方案,有早期比較經典的Quartz,近幾年版本迭代不太活躍,也有后起之秀XXL-JOB 版本迭代比較活躍,也是目前很多公司推崇的解決方案,對任務的管理、監(jiān)控、日志等功能比較齊全,可以參考其官方,這里就不再多述。

自處理

盡管上面開源的第三方解決方案,已經足夠成熟、完善,但相對來說,還是有些重,對于一些系統(tǒng)規(guī)模不是很大,一些簡單的任務調度需求,完全可以進行簡單改造來滿足這些任務調度功能。

盡管簡單,它一樣可以很實用、很健壯,以下是2種借助redis的處理思路。

(1) @Scheduled為主,redis為輔

通過@Scheduled注解的調度任務,在分布式環(huán)境運行,一個明顯的問題,就是同一個任務,可能會在多個機器同時并發(fā)執(zhí)行,如何避免,很自然就想到通過redis分布式鎖處理,來避免任務并發(fā)執(zhí)行,鎖定時間可以設置0.75個執(zhí)行周期,以下是偽碼

	@Scheduled(fixedDelay = 60000, initialDelay = 1000)
	public void task1() {
		
		// 鎖定
		boolean isLock = redisLock.lock("my-task-1", 60000 * 0.75);
		if (!isLock) return;
		
		// 任務邏輯
		doSomething();
	}

可以看出,這種方式,任務周期誤差比較大,比較粗糙,特點就是邏輯簡單,適用于精度要求較低的場景。

(2) redis為主,@Scheduled為輔

由于通過@Scheduled來配置執(zhí)行周期,在分布式環(huán)境,很難保證周期的精度,這時候可以把@Scheduled僅作為嘗試申請執(zhí)行的一個定時掃描任務,真實的執(zhí)行周期由redis的過期時間來管理,這種方式,任務周期精度就會好很多,以下是偽碼:

按固定頻率執(zhí)行:

	/*
	 * redis為主,@Scheduled為輔(按固定頻率執(zhí)行任務)
	 * 
	 * note:
	 * a. @Scheduled注解中fixedDelay,該參數(shù)僅作為嘗試申請執(zhí)行任務, 通??梢栽O置小些。
	 * b. 任務執(zhí)行周期或間隔,值為redisLock鎖定的時間。
	 * 
	 */
	@Scheduled(fixedDelay = 5000, initialDelay = 1000)
	public void task2() {
		
		// 鎖定
		boolean isLock = redisLock.lock("my-task-2", 真實任務周期);
		if (!isLock) return;
		
		// 任務邏輯
		doSomething();
		
	}

按固定間隔執(zhí)行:

	/*
	 * redis為主,@Scheduled為輔(按固定間隔執(zhí)行)
	 * 
	 * note:
	 * a. @Scheduled注解中fixedDelay,該參數(shù)僅作為嘗試申請執(zhí)行任務, 通??梢栽O置小些。
	 * b. 任務執(zhí)行周期或間隔,值為redisLock鎖定的時間。
	 * 
	 */
	@Scheduled(fixedDelay = 5000, initialDelay = 1000)
	public void task3() {
		
		// 鎖定1: 避免任務并行
		boolean isLock = redisLock.lock("my-task-3", 真實任務間隔);
		if (!isLock) return;
		
		// 任務邏輯
		doSomething();
		
		// 鎖定2: 間隔時間
		redisLock.expire("my-task-3", 真實任務間隔);
		
	}

按cron表達式執(zhí)行:可通過注解@Scheduled參數(shù)fixedDelay,來調整周期精度。

	/*
	 * redis為主,@Scheduled為輔(cron表達)
	 * 
	 * note:
	 * a. @Scheduled注解中fixedDelay,該參數(shù)僅作為嘗試申請執(zhí)行任務, 通??梢栽O置小些。
	 * b. 任務執(zhí)行周期或間隔,值為redisLock鎖定的時間。
	 * c. 由CronHelper解析cron表達式,計算下一次運行間隔時間
	 */
	@Scheduled(fixedDelay = 5000, initialDelay = 1000)
	public void task4()  {
		
		// 鎖定
		boolean isLock = redisLock.lock("my-task-4", CronHelper.getNextDelayTime());
		if (!isLock) return;
		
		// 任務邏輯
		doSomething();		
	}

以上只偽碼,可以看出改造成本比較少,也足夠靈活,其中RedisLock可以參考前面整理的文章:分布式鎖-java,至于CronHelper類,網(wǎng)上應該有類似資源,也不妨自己實現(xiàn)一下,應該比排序算法有趣的多。

再就是任務的運行,不能保證負載均衡,如果的確有這方面需求,通過redis隊列也可以實現(xiàn),邏輯也不會太復雜。

個人認為:

這種自處理方式,借助redis還是可以保障它的高可用性、并發(fā)性能,它的主要缺陷,就是代碼語義不夠清晰,在維護上,容易受注解@Scheduled定時參數(shù)影響,實際業(yè)務場景,盡量封裝一下,提高可讀性。

常見問題

(1) 線程池的大小,建議幾種任務就幾個線程,多了也浪費,如果太小,任務耗時長時,就會出現(xiàn)任務間干擾。

(2) 如果任務有嚴格的并行限制,可以通過分布式鎖防護一下。

總結

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • java讀取圖片并顯示方式

    java讀取圖片并顯示方式

    這篇文章主要介紹了java讀取圖片并顯示方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • SpringBoot Redis實現(xiàn)接口冪等性校驗方法詳細講解

    SpringBoot Redis實現(xiàn)接口冪等性校驗方法詳細講解

    這篇文章主要介紹了SpringBoot Redis實現(xiàn)接口冪等性校驗方法,近期一個老項目出現(xiàn)了接口冪等性校驗問題,前端加了按鈕置灰,依然被人拉著接口參數(shù)一頓輸出,還是重復調用了接口,通過復制粘貼,完成了后端接口冪等性調用校驗
    2022-11-11
  • 解決Nacos成功啟動但是無法訪問 (Connection refused)

    解決Nacos成功啟動但是無法訪問 (Connection refused)

    這篇文章主要介紹了解決Nacos成功啟動但是無法訪問 (Connection refused)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • spring boot(三)之Spring Boot中Redis的使用

    spring boot(三)之Spring Boot中Redis的使用

    這篇文章主要介紹了spring boot(三)之Spring Boot中Redis的使用,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-05-05
  • 使用springboot實現(xiàn)上傳文件時校驗文件是否有病毒

    使用springboot實現(xiàn)上傳文件時校驗文件是否有病毒

    在SpringBoot中實現(xiàn)文件上傳時的病毒校驗,可以使用ClamAV、Metascan或VirusTotal等工具,這些工具通過掃描上傳的文件,可以有效地檢測和阻止惡意軟件的傳播,安裝和配置ClamAV服務的步驟如下:下載并安裝ClamAV二進制文件,配置clamd.conf文件
    2025-01-01
  • 排序算法的Java實現(xiàn)全攻略

    排序算法的Java實現(xiàn)全攻略

    這篇文章主要介紹了排序算法的Java實現(xiàn),包括Collections.sort()的使用以及各種經典算法的Java代碼實現(xiàn)方法總結,超級推薦!需要的朋友可以參考下
    2015-08-08
  • Spring?Cloud?Alibaba?Nacos兩種檢查機制

    Spring?Cloud?Alibaba?Nacos兩種檢查機制

    這篇文章主要介紹了Spring?Cloud?Alibaba?Nacos兩種檢查機制,作為注冊中心不止提供了服務注冊和服務發(fā)現(xiàn)功能,它還提供了服務可用性監(jiān)測的機制,下面我們就一起進入文章了解具體詳情吧
    2022-05-05
  • 簡單了解JavaBean作用及常用操作

    簡單了解JavaBean作用及常用操作

    這篇文章主要介紹了簡單了解JavaBean作用及常用操作,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-05-05
  • Java 時間日期詳細介紹及實例

    Java 時間日期詳細介紹及實例

    這篇文章主要介紹了Java 時間日期詳細介紹及實例的相關資料,需要的朋友可以參考下
    2017-01-01
  • 關于synchronized的參數(shù)及其含義

    關于synchronized的參數(shù)及其含義

    這篇文章主要介紹了synchronized的參數(shù)及其含義詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10

最新評論