雪缘园足彩:排查@Scheduled定時任務堵塞的問題

來源:明宇碼海游    2020/2/23 17:56:23
責任編輯:王強
字體:

雪缘园首页 www.606887.live

樓主說下你的具體需求吧,你要實現在什么時候進行調度? 你每3分鐘循環一次的話,你把間隔時間設置長一些,會不會出現這次在執行的時候,上一次的還沒有執行完呢,另外用debug模式跟蹤下就知道了!

前幾天同事反饋一個spring mvc項目里面定時任務有時候沒執行(查詢的數據庫任務日志記錄表)。后來查看info日志,發現好多定時任務都延時執行了,都不是在設定的時間內。 首先想到@Scheduled默認是單線程的,檢查下配置文件是不是沒有配置定時任務的線程池,配置信息如下:<task:scheduler id="myScheduler" pool-size="3"/><task:annotation-driven scheduler="myScheduler" mode="proxy"/>發現配置了線程池,但是pool-size是2,全局搜索了下@Scheduled注解發現有10多個^-^,而且很多配置的時間都很接近,我們將pool-size設置大點。任務計劃

定時任務本身不會有沖突,有沖突的是任務中操作處理的資源或數據,需要對有寫入的文件或數據進行排它鎖,保障線程處理的安全性。

新建個工程,寫幾行代碼測試下@Scheduled堵塞的情況:默認單線程<task:annotation-driven /> 不做其他設置,配置2個同一時刻執行的任務,第一個任務執行需2分鐘,結果發現任務2延時了2分鐘才被執行定時任務延時執行

定時器的操作可以是掃描保存時間的表, 然后比對表中保存的執行時間和系統當前時間,如果滿足條件就觸發操作, 如果不滿足就不管~~~ 不過這個spring的任務時間間隔要設置比較短

增加調度線程池配置<task:scheduler id="myScheduler" pool-size="4"/><task:annotation-driven scheduler="myScheduler" mode="proxy"/>,線程池pool-size大于任務的數量。再次執行剛才的代碼,發現沒有延時。定時任務執行

有兩種方法: 第一種當然你可以把Scheduled寫到xml文件中進行配置。 第二種在你的類前面添加 @PropertySource("classpath:root/test.props") 然后修改你的@Scheduled(cron="0/5 * * * * ? ") 為 @Scheduled(cron="${jobs.schedule}") 最后test.p。

我們再試下@Scheduled(fixedDelay = 3000) 這種定時間隔的任務。我們定義2個任務,都是每隔3秒執行一次(其中任務1執行時暫停2秒),結果發現任務1每隔5秒才執行一次。我們知道fixedDelay 代表的是上一次任務結束后到下一次任務開始的間隔時間,理論上第一次執行時間15:23:51,第二次執行應該是15:23:54,然而現在是15:23:56。相同任務定時輪詢執行時被堵塞了,任務2正常(開啟了線程池,可以在同一時間執行不同的多個任務,這個是怎么堵塞的有點想不明白)定時任務延時

有兩種方法: 第一種當然你可以把Scheduled寫到xml文件中進行配置。 第二種在你的類前面添加 @PropertySource("classpath:root/test.props") 然后修改你的@Scheduled(cron="0/5 * * * * ? ") 為 @Scheduled(cron="${jobs.schedule}") 最后test.p。

我們將任務1改成異步模式,增加@Async("myScheduler")注解,注解里面的value是定義的調度線程池的id,結果任務均按照3秒的間隔定時執行,任務1間隔正常,沒異步加注解前是5秒執行一次。定時任務執行請注意:本文為編輯制作專題提供的資訊,頁面顯示的時間僅為生成靜態頁面時間而非具體內容事件發生的時間,由此給您帶來的不便敬請諒解!

你要描述一下怎么不行,是報異常了? 如果是,很可能是你的dao層配置了事務處理,監控的包里是不包含你現在這個定時器類的(比如你放到了Controller層的action類上了)

擴展閱讀,根據您訪問的內容系統為您準備了以下內容,希望對您有幫助。

java scheduledexecutor 中一個定時任務,如果還沒到時間的話會不會一直阻塞那個線程

肯定要占用線程的,定義任務后,任務被放到線程池里,有另外一個線程對線程池輪詢,條件滿足就執行,執行完了,任務依然在線程池輪詢,等待下一次執行。

Spring使用@Scheduled進行定時任務,定的時間可否變

定時任務的實現方式有多種,例如JDK自帶的Timer+TimerTask方式,Spring 3.0以后的調度任務(Scheduled Task),Quartz等。

Timer+TimerTask是最基本的解決方案,但是比較遠古了,這里不再討論。Spring自帶的Scheduled

Task是一個輕量級的定時任務調度器,支持固定時間(支持cron表達式)和固定時間間隔調度任務,支持線程池管理。以上兩種方式有一個共同的缺點,那就是應用服務器集群下會出現任務多次被調度執行的情況,因為集群的節點之間是不會共享任務信息的,每個節點上的任務都會按時執行。Quartz是一個功能完善的任務調度框架,特別牛叉的是它支持集群環境下的任務調度,當然代價也很大,需要將任務調度狀態序列化到數據庫。Quartz框架需要10多張表協同,配置繁多,令人望而卻步...

經過折中考慮,還是選擇了Spring的Scheduled Task來實現定時任務。如下:

1. Spring配置文件application-context.xml中添加task命名空間和描述。

[html] view plain copy

<beans xmlns=""

xmlns:task=""

xsi:schemaLocation="

/spring-beans.xsd

/spring-task.xsd">

2. 添加調度器和線程池聲明。

[html] view plain copy

<task:executor id="taskExecutor" pool-size="10" />

<task:annotation-driven executor="taskExecutor" />

3. 實現調度方法?;窘峁谷縵攏?p>

[html] view plain copy

package com.netease.yx.service;

import org.springframework.scheduling.annotation.Scheduled;

import org.springframework.stereotype.Service;

@Service

public class ScheduledService {

@Scheduled(cron = "0 0 5 * * *")

public void build() {

System.out.println("Scheduled Task");

}

}

@Scheduled注解支持秒級的cron表達式,上述聲明表示每天5點執行build任務。

前文已經提過,這種方式在單臺應用服務器上運行沒有問題,但是在集群環境下,會造成build任務在5點的時候運行多次,遺憾的是,Scheduled Task在框架層面沒有相應的解決方案,只能靠程序員在應用級別進行控制。

如何控制看

1. 無非是一個任務互斥訪問的問題,聲明一把全局的逗鎖地作為互斥量,哪個應用服務器拿到這把逗鎖地,就有執行任務的權利,未拿到逗鎖地的應用服務器不進行任何任務相關的操作。

2.這把逗鎖地最好還能在下次任務執行時間點前失效。

在項目中我將這個互斥量放在了redis緩存里,1小時過期,這個過期時間是由任務調度的間隔時間決定的,只要小于兩次任務執行時間差,大于集群間應用服務器的時間差即可。

完整定時任務類如下:

[html] view plain copy

package com.netease.yx.service;

import javax.annotation.Resource;

import org.apache.commons.lang3.time.DateUtils;

import org.springframework.scheduling.annotation.Scheduled;

import org.springframework.stereotype.Service;

import com.netease.yx.service.ICacheService;

@Service

public class ScheduledService {

@Resource

private ICacheService cache = null;

private static String CACHE_LOCK = "cache_lock";

private static int EXPIRE_PERIOD = (int)DateUtils.MILLIS_PER_HOUR / 1000;

@Scheduled(cron = "0 0 5 * * *")

public void build() {

if (cache.get(CACHE_LOCK) == null) {

cache.set(CACHE_LOCK, true, EXPIRE_PERIOD);

doJob();

}

}

}本回答被提問者采納

spring自動任務task:scheduled執行一段時間后不執行了。

樓主說下你的具體需求吧,你要實現在什么時候進行調度?

你每3分鐘循環一次的話,你把間隔時間設置長一些,會不會出現這次在執行的時候,上一次的還沒有執行完呢,另外用debug模式跟蹤下就知道了!追問3分鐘應該是足夠的,只是一個很小的東西,不會進去不來的。

另外,我用timer寫了一個同樣的方法執行,但是timer比它的執行頻率更高一些,是20秒執行一次,沒有出現這個問題。本回答被提問者采納

為您準備的好內容:

雪缘园首页 www.606887.live true //getqq.haoxyx.com/g/3513/35139608.html report 7052 前幾天同事反饋一個springmvc項目里面定時任務有時候沒執行(查詢的數據庫任務日志記錄表)。后來查看info日志,發現好多定時任務都延時執行了,都不是在設定的時間內。首先想到@Scheduled默認是單線程的,檢查下配置文件是不是沒有配置定時任務的線程池,配置信息如下:<task:schedulerid="myScheduler"pool-size="3"/><task:annotation-drivenscheduler="
最近關注
首頁推薦
熱門圖片
最新添加資訊
    24小時熱門資訊
    精彩資訊
    精彩推薦
    熱點推薦
    真視界
    精彩圖片
    社區精粹
    關于本站 | 廣告服務 | 手機版 | 商務合作 | 免責申明 | 雪缘园首页 | 聯系我們
    Copyright © 2004-2017 www.606887.live All Rights Reserved. 好心游戲網 版權所有
    京ICP備10044368號-1 京公網安備11010802011102號
    {ganrao}