在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

說說Spring定時任務如何大規模企業級運用

OSC開源社區 ? 來源:阿里云云原生 ? 作者:姚輝(千習) ? 2022-11-04 09:36 ? 次閱讀

Spring 定時任務簡介

Cloud Native

定時任務是業務應用開發中非常普遍存在的場景(如:每分鐘掃描超時支付的訂單,每小時清理一次數據庫歷史數據,每天統計前一天的數據并生成報表等等),解決方案很多,Spring 框架提供了一種通過注解來配置定時任務的解決方案,接入非常的簡單,僅需如下兩步:

1. 在啟動類上添加注解@EnableScheduling


@SpringBootApplication
@EnableScheduling  // 添加定時任務啟動注解
public class SpringSchedulerApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringSchedulerApplication.class, args);
    }
}
2. 開發定時任務 Bean 并配置相應的定時注解@Scheduled

@Component
public class SpringScheduledProcessor {


  /**
     * 通過Cron表達式指定頻率或指定時間
     */
    @Scheduled(cron = "0/5 * * * * ?")
    public void doSomethingByCron() {
        System.out.println("do something");
    }
    
  /**
     * 固定執行間隔時間
     */
    @Scheduled(fixedDelay = 2000)
    public void doSomethingByFixedDelay() {
        System.out.println("do something");
    }


    /**
     * 固定執行觸發頻率
     */
    @Scheduled(fixedRate = 2000)
    public void doSomethingByFixedRate() {
        System.out.println("do something");
    } 
}

Spring 定時任務原理

Cloud Native

運行原理

Spring 定時任務核心邏輯主要在 spring-context 中的 scheduling 包中,其主要結構包括:

定時任務解析:通過 ScheduledTasksBeanDefinitionParser 對 XML 定義任務配置解析;也可通過 ScheduledAnnotationBeanPostProcessor對@Scheduled 注解進行任務解析(常見模式)。

定時任務注冊登記:上述解析獲得的 Task 任務配置會被注冊登記至 ScheduledTaskRegistrar 中以備運行使用。

任務定時運行:完成所有任務注冊登記后,會通過 TaskScheduler 正式地定時運行相關任務,底層通過 JDK 的 ScheduledExecutorService 運行任務。

a6912d5a-5b87-11ed-a3b6-dac502259ad0.jpg

業務邏輯會將被包裝在 ScheduledMethodRunnable 類中,其中包含了待執行的目標業務對象 Bean 和業務方法,該 Runnable 對象在運行時會被提交至 ScheduledExecutorService 調度線程池完成任務的定時運行。

a6a9892c-5b87-11ed-a3b6-dac502259ad0.jpg

從上圖可以看到真正要運行的業務邏輯 ScheduledMethodRunnable 會被 ReschedulingRunnable、DelegatingErrorHandlingRunnable 做了代理擴展,這兩層代理擴展具有如下意義:

DelegatingErrorHandlingRunnable:為業務方法運行異常進行包裝處理,提供了自定義異常處理機制、解決 JDK 原生定時任務執行異常后任務失效問題。

ReschedulingRunnable:提供了擴展的定時模式支持,可支持基于 Trigger 接口自定義實現獲取下次觸發時間定時調度,默認提供的 Cron 定時通過此方式進行擴展實現。

定時模式

Spring 定時任務 Task 類的模式主要可分為兩類:IntervalTask 和 TriggerTask。前者表示固定頻率間隔執行,后者則采用 Trigger 觸發器模式實現定時調度,Cron 表達式配置為該模式實現。

FixedDelay:按固定延遲頻率執行,任務下一次觸發時間=上一次執行結束時間+Delay 延遲時間。

a6c1e63e-5b87-11ed-a3b6-dac502259ad0.jpg

FixedRate:按固定頻率觸發執行,任務下一次觸發時間=上一次觸發時間+Delay 延遲時間。如果上一次執行方法不結束會阻塞下一次任務執行。

a6d5c654-5b87-11ed-a3b6-dac502259ad0.jpg

Cron 表達式:按 Cron 表達式計算下一次觸發時間,任務下一次觸發時間=cron(上一次執行結束時間)。

進階擴展

線程池運行

默認配置下底層運行的線程池為單線程,單線程的運行模型在任務量較多且觸發頻率較高的情況下,一旦某個任務發生阻塞會導致所有后續定時任務運行阻斷,這對業務運行帶來嚴重隱患。常見可采用如下方式:

配置定時執行線程池:常見基于配置 Spring Boot 配置(spring.task.scheduling.pool.size=線程數),線程數大小取決于任務數及調度頻率合理配置。

配置異步任務:在 spring context 中的 scheduling 模塊下提供了@EnableAsync 和@Async,可用于開啟任務異步執行,實現定時調度線程池非阻塞運行。該模式下存在一些不足之處:異常處理需要走異步調用的 AsyncUncaughtExceptionHandler 異常處理接口實現,同步/異步定時任務異常處理機制不統一,另外異步模式增加了業務應用的線程開銷。


@Scheduled(fixedDelay = 2000)
@Async
public void test() {
    System.out.println(DateUtil.now()+ " test.");
}

異常統一處理

定時任務運行可設置統一異常處理,基于 ErrorHandler 接口開發對應異常處理實現類。對應的異常實現處理類需要注入到核心的 ThreadPoolTaskScheduler 中,用戶可以通過自定義 TaskSchedulerCustomizer 方式來實現 ErrorHandler 自定義異常處理 Bean 注入至 ThreadPoolTaskScheduler 中。


@Component
public class DemoTaskSchedulerCustomizer implements TaskSchedulerCustomizer {
    @Override
    public void customize(ThreadPoolTaskScheduler taskScheduler) {
        taskScheduler.setErrorHandler(new DemoErrorHandler());
    }


    private class DemoErrorHandler implements ErrorHandler {
        @Override
        public void handleError(Throwable throwable) {
            System.out.println("異常統一處理.");
        }
    }
}

原生 Spring 定時任務在企業中遇到的問題

Cloud Native

任務重復執行

Spring 定時任務,只要有注解就會執行,在分布式場景下,所有機器代碼一致,會導致同一個任務在多臺機器上重復執行。一般的解決方案是搶鎖觸發,分布式鎖實現形式可采用 DB、ZK、Redis 等方式。

a6f6147c-5b87-11ed-a3b6-dac502259ad0.jpg

示例代碼如下:


@Component
@EnableScheduling
public class MyTask {
    /**
     * 每分鐘的第30秒跑一次
     */
    @Scheduled(cron = "30 * * * * ?")
    public void task1() throws Exception {
        String lockName = "task1";
        if (tryLock(lockName)) {
            System.out.println("hello cron");
            releaseLock(lockName);
        } else {
            return;
        }
    }
    private boolean tryLock(String lockName) {
        //TODO
        return true;
    }
    
    private void releaseLock(String lockName) {
        //TODO
    }
}
如上圖所示,當任務觸發時 3 個 server 會對任務搶鎖,僅獲得任務鎖的 server 才能執行對應任務業務邏輯。當前的這個設計,仔細一點的同學可以發現,其實還是有可能導致任務重復執行的。比如任務執行的非常快,A 這臺機器搶到鎖,執行完任務后很快就釋放鎖了。B 這臺機器后搶鎖,還是會搶到鎖,再執行一遍任務。

無管控無運維

原生 Spring 定時任務沒有控制臺,無法動態的新增和修改定時任務,如果要修改定時任務的配置(比如每分鐘跑一次改成每小時跑一次),必須修改代碼重新發布應用。同時原生Spring定時任務也沒有運維操作,不支持運行一次任務,任務失敗了也不支持重跑任務。

如果要自研的可視化控制臺來實現整套任務可視化管控體系,需要一定的前后端研發成本和服務部署成本投入。對于需要自建的用戶而言,可參考以下需求功能進行自有平臺建設:

任務的可視化動態配置

任務執行運行詳細信息的可視化查看

任務執行日志、執行調用鏈、調度觸發的可視化查詢分析

業務應用間任務信息配置權限隔離

無業務失敗通知能力

對于完整企業級定時任務運用方案中,報警通知能力必不可少,任務跑失敗了需要及時通知到用戶,否則可能產生故障。

原生 Spring 定時任務不支持報警通知能力,如果要自研,可以參考上一章節中《異常統一處理》對任務失敗的信息進行收集,構建相應的異常處理機制(包括對接各類報警平臺進行異常消息通知處理,定義異常等級和類別進行不同的通知策略),然后進行定時任務報警通知。

a70ba49a-5b87-11ed-a3b6-dac502259ad0.jpg

無在線排查分析能力

定時任務在運行過程中會存在各種各樣的問題,比如:執行失敗、執行耗時、執行卡住等,這些都需要在后期實際運維去定位快速分析。在對應分析過程中沒有高效在線排查能力的話將遇到很多棘手的問題:

集群中任務對應時間點是跑在哪個機器上無從可知

需要在大量的業務應用日志中去檢索對應時點的定時任務執行日志,需要自行對接日志服務改善

如果任務涉及多個跨服務調用,無法定位執行異常點或執行耗時點,需要自建全鏈路追蹤來支持

阿里云 Spring 定時任務企業級解決方案

Cloud Native

接下來主要講下如何利用公有云上任務調度 SchedulerX 輕松接入基于 Spring 開發的定時任務。前面聊了基于 Spring 原生功能在使用過程中面臨的問題及需要自行處理解決的相關方案,可以看到僅針對企業級最基礎的運用場景下就需要花費較多的改造投入及相關服務后續運維投入。通過接入 SchedulerX 任務調度平臺,原本 Spring 定時任務使用者可無縫且 0 改造獲得企業級運用所需能力,同時降低了自研部署運維定時服務相關組件的技術成本。

如何接入

對于 SchedulerX 新用戶而言接入僅需三步(參考附件接入手冊):

依賴 SchedulerX 的 Spring Boot 版 SDK 完成調度平臺接入(版本>=1.7.2,老用戶僅升級 SDK 版本即可)

配置文件添加配置項,配置開啟后 Spring 定時調度器將不運行相關任務(未配置情況下,不會主動接管原 Spring 定時任務運行,在配置開啟前不會影響原本定時任務業務運行)


# 配置表示由SchedulerX接管Spring定時任務運行
spring.schedulerx2.task.scheduling.scheduler=schedulerx

控制臺上在對應應用分組下創建任務配置定時觸發。也可以選擇開啟自動同步任務配置方式(可選)


# 自動同步Spring定時任務至調度平臺,無需單獨手動創建(默認不開啟)
spring.schedulerx2.task.scheduling.sync=true

接入優勢

白屏管控和運維

提供白屏控制臺可以動態新增、修改、啟用、禁用任務,支持運行一次、原地重跑、重刷數據、停止任務、標記成功等運維操作。 a7287b56-5b87-11ed-a3b6-dac502259ad0.pnga7406996-5b87-11ed-a3b6-dac502259ad0.pnga75ad128-5b87-11ed-a3b6-dac502259ad0.png

可視化在線排查問題

支持執行記錄查看、執行業務日志查詢、執行全鏈路追蹤。
a772929a-5b87-11ed-a3b6-dac502259ad0.pnga78a0f42-5b87-11ed-a3b6-dac502259ad0.png

豐富的報警通知

SchedulerX 提供豐富的報警通知能力,支持短信、電話、郵件、webhook 報警,支持報警聯系人組和報警歷史,可白屏動態配置。 a79fd7d2-5b87-11ed-a3b6-dac502259ad0.pnga7df0cc2-5b87-11ed-a3b6-dac502259ad0.png

其他優勢

無改造成本的平臺接入方案。

無需額外獨立運維調度服務平臺或其他第三方組件服務。

任務運行在集群環境中具備穩定高可靠支持,規避了原生框架存在的重復執行問題,具備故障自動轉移能力。

在企業內多個團隊可共享一套平臺使用,通過命名空間和應用分組實現各團隊任務配置數據隔離及環境隔離。

總結

Cloud Native

本文主要從 Spring 定時任務的運行機制進行剖析闡述,并對如何擴展框架原生能力以滿足企業級生產環境運行定時任務所需各種場景提出了相應的建議,用戶可作參考構建自己內部定時任務方案。同時就阿里云上提供的任務調度服務如何接入 Spring 定時任務的運行進行講解,并簡單展示了接入后所帶來的企業級能力。最后歡迎有定時任務業務需求用戶可先通過基礎免費額度體驗感受云上服務帶來便捷。

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • spring
    +關注

    關注

    0

    文章

    340

    瀏覽量

    14398

原文標題:說說Spring定時任務如何大規模企業級運用

文章出處:【微信號:OSC開源社區,微信公眾號:OSC開源社區】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    SAS走進企業級存儲應用

    SAS走進企業級存儲應用串行SCSI(SAS)的出現已經有幾年了。2005年,在主要的接口技術中,由于OEM服務器制造商和系統集成商開始提供串行SCSI解決方案,企業級存儲市場將會顯現革命性的進展
    發表于 11-13 21:58

    關于stm32系統定時任務的問題

    在用stm32做一個飛控程序時。需要用到上面這種系統循環定時任務,有一個問題:在System_Task_Loop函數里面,有1ms 、2ms、5ms的循環任務,但是他的這些定時是怎么得到的?是隨便
    發表于 10-10 23:43

    Linux系統定時任務Crond

    會定期(默認每分鐘檢查一次)檢查系統中是否有要執行的任務工作,如果有,便會根據其預先設定的定時任務規則自動執行該定時任務工作,這個crond定時任務服務就相當于我們平時早起使用的鬧鐘一
    發表于 07-05 06:22

    linux的循環定時任務

    linux循環定時任務
    發表于 05-20 14:59

    定時任務的發展史是怎么樣的

    定時任務是互聯網行業里最常用的服務之一,本文給大家介紹定時任務在我司的發展歷程。 linux系統中一般使用crontab命令來實現,在Java世界里,使用最廣泛的就是quartz了。我司
    發表于 07-18 17:38 ?0次下載
    <b class='flag-5'>定時任務</b>的發展史是怎么樣的

    SpringBoot如何實現動態增刪啟停定時任務

    spring boot項目中,可以通過 @EnableScheduling 注解和@Scheduled注解實現定時任務,也可以通過SchedulingConfigurer接口來實現定時任務。但是
    的頭像 發表于 09-24 09:49 ?3007次閱讀
    SpringBoot如何實現動態增刪啟停<b class='flag-5'>定時任務</b>

    Python定時任務的實現方式

    在日常工作中,我們常常會用到需要周期性執行的任務,一種方式是采用 Linux 系統自帶的 crond 結合命令行實現。另外一種方式是直接使用Python。接下來整理的是常見的Python定時任務
    的頭像 發表于 10-08 15:20 ?6557次閱讀

    解析Golang定時任務庫gron設計和原理

    正巧,最近看到了 gron 這個開源項目,它是用 Golang 實現一個并發安全的定時任務庫。實現非常簡單精巧,代碼量也不多。今天我們就來一起結合源碼看一下,怎樣基于 Golang 的能力做出來一個【定時任務庫】。
    的頭像 發表于 12-15 13:57 ?1400次閱讀

    求一種SpringBoot定時任務動態管理通用解決方案

    SpringBoot的定時任務的加強工具,實現對SpringBoot原生的定時任務進行動態管理,完全兼容原生@Scheduled注解,無需對原本的定時任務進行修改
    的頭像 發表于 02-03 09:49 ?835次閱讀

    Spring Boot中整合兩種定時任務的方法

    Spring + SpringMVC 環境中,一般來說,要實現定時任務,我們有兩中方案,一種是使用 Spring 自帶的定時任務處理器 @Scheduled 注解,另一種就是使用第
    的頭像 發表于 04-07 14:55 ?1613次閱讀
    <b class='flag-5'>Spring</b> Boot中整合兩種<b class='flag-5'>定時任務</b>的方法

    Spring Boot中如何使用定時任務

    本文介紹在 Spring Boot 中如何使用定時任務,使用非常簡單,就不做過多說明了。
    的頭像 發表于 04-12 10:56 ?1021次閱讀

    如何動態添加修改刪除定時任務

    如何動態添加修改刪除定時任務?那么我們一起看看具體怎么實現,先看下本節大綱: (1)思路說明; (2)代碼解析; (3)修改定時任務執行周期特別說明;
    的頭像 發表于 04-12 11:06 ?1138次閱讀

    Linux如何使用cron進行定時任務的操作

    按計劃執行命令對于計算機來說非常重要,因為假如我親自去執行一些任務的話,可能會因為多方面因素不能按時執行,所以定時任務就顯得非常重要了! cron就是一個能夠執行定時任務的命令,其實該命令本身不難,下面小編帶您詳細了解!
    的頭像 發表于 05-12 16:27 ?2106次閱讀

    python定時任務實踐

    由于程序需求,監測配置變化需要設置定時任務,每分鐘執行一次,對任務持久化要求不高,不需要時可以關閉定時任務
    的頭像 發表于 05-20 17:53 ?1018次閱讀
    python<b class='flag-5'>定時任務</b>實踐

    linux定時任務的用法總結

    習慣了使用 windows 的計劃任務,使用 linux 中的 crontab 管理定時任務時很不適應。
    的頭像 發表于 08-14 18:16 ?911次閱讀
    linux<b class='flag-5'>定時任務</b>的用法總結
    主站蜘蛛池模板: 国产yw855.c免费观看网站 | 欧美三级影院 | 久久第一页 | 日本加勒比在线视频 | 午夜影院普通 | 模特精品视频一区 | 免费一级在线 | 四虎影免看黄 | 狠狠的操 | 天堂网在线最新版官网 | 麒麟色欧美影院在线播放 | 国产三级国产精品 | 手机在线完整视频免费观看 | 久久久99精品免费观看精品 | 加勒比一到三区 | 国产免费一区二区三区在线 | 欧美高清一区二区三 | 深爱五月激情五月 | 国产在线h | 黄色毛片播放 | 一级毛片在线 | 4虎影视国产在线观看精品 4虎影院永久地址www | 日韩免费三级电影 | 亚洲综合国产一区二区三区 | 99久久精品费精品国产一区二 | 天天色天天色 | 国产特黄特色的大片观看免费视频 | 天堂欧美 | 777777777妇女亚洲| 视频在线观看网站免费 | 西西人体44renti大胆亚洲 | 久久国产美女 | 日本三级456| 亚洲综合久久综合激情久久 | 免费看欧美一级特黄a大片 免费看欧美一级特黄a大片一 | 精品美女在线观看 | 亚洲色五月 | 99香蕉国产| 午夜视频色 | 午夜影院免费体验 | 一区二区三区电影 |