SpringBoot分布式定時任務實戰:告別重復執行的煩惱

場景再現:你剛部署完基于SpringBoot的集群服務,凌晨3點突然收到監控告警——優惠券發放量超出預算兩倍!檢查日志發現,兩個節點同時執行了定時任務。這種分布式環境下的定時任務難題,該如何徹底解決?

本文將手把手帶你攻克這些難題:

  • 剖析傳統@Scheduled注解在分布式環境失效的根源
  • 實戰演示三種主流分布式定時任務方案
  • 生產環境避坑指南與性能優化建議

一、為什么單機方案在分布式環境下失效?

當我們的服務以集群方式部署時,每個節點的定時任務都會獨立運行。這會導致:

  1. 重復任務執行導致業務異常(如重復扣款)
  2. 數據庫被多個節點同時操作引發鎖沖突
  3. 無法實現任務的動態擴容縮容

二、五大分布式定時任務方案選型

方案實現難度可靠性功能豐富度適用場景
數據庫鎖★★☆☆☆★★☆☆☆★☆☆☆☆小型項目快速實現
Redis分布式鎖★★★☆☆★★★☆☆★★☆☆☆輕量級任務調度
Zookeeper選舉★★★★☆★★★★☆★★☆☆☆強一致性場景
Quartz集群★★★★☆★★★★☆★★★★★企業級復雜調度
Elastic-Job★★★☆☆★★★★★★★★★★互聯網高并發場景

結論:推薦Elastic-Job(功能強大)或Spring Scheduler + Redis分布式鎖(輕量快速)


三、方案一:Elastic-Job + SpringBoot實戰

3.1 引入Maven依賴
<!-- ElasticJob-Lite -->
<dependency><groupId>org.apache.shardingsphere.elasticjob</groupId><artifactId>elasticjob-lite-spring-boot-starter</artifactId><version>3.0.3</version>
</dependency>
3.2 配置Zookeeper注冊中心
elasticjob:reg-center:server-lists: localhost:2181namespace: elasticjob-demo
3.3 實現定時任務類
public class OrderTimeoutJob implements SimpleJob {@Overridepublic void execute(ShardingContext context) {// 獲取當前分片參數int shardIndex = context.getShardingItem();// 分片策略示例:按訂單ID取模分片List<Long> orderIds = fetchTimeoutOrders(shardIndex);orderIds.forEach(this::cancelOrder);}private List<Long> fetchTimeoutOrders(int shard) {// 實現分片查詢邏輯return orderRepository.findTimeoutOrders(shard);}
}

關鍵配置參數

jobs:orderTimeoutJob:elasticJobClass: com.example.OrderTimeoutJobcron: 0 0/5 * * * ?shardingTotalCount: 3overwrite: true

四、方案二:Spring Scheduler + Redis分布式鎖

4.1 實現Redis鎖工具類
public class RedisDistributedLock {private static final String LOCK_PREFIX = "schedule:lock:";private static final int LOCK_EXPIRE = 30;@Autowiredprivate StringRedisTemplate redisTemplate;public boolean tryLock(String lockKey) {String key = LOCK_PREFIX + lockKey;return redisTemplate.opsForValue().setIfAbsent(key, "locked", LOCK_EXPIRE, TimeUnit.SECONDS);}public void unlock(String lockKey) {redisTemplate.delete(LOCK_PREFIX + lockKey);}
}
4.2 定時任務增強實現
@Component
public class CouponExpireJob {@Autowiredprivate RedisDistributedLock redisLock;@Scheduled(cron = "0 0 3 * * ?")public void processExpiredCoupons() {if (!redisLock.tryLock("couponJob")) {return;}try {// 真正的業務邏輯couponService.processExpired();} finally {redisLock.unlock("couponJob");}}
}

五、生產環境避坑指南

  1. 時鐘同步問題:所有節點必須使用NTP同步時間
  2. 鎖過期時間:預估任務最大執行時間,建議設置超時時間的1.5倍
  3. 故障轉移:使用Elastic-Job時開啟故障轉移配置
    jobs:myJob:failover: true
    
  4. 動態擴容:Elastic-Job支持運行時修改分片數量
  5. 監控告警:集成Prometheus監控任務執行情況

六、性能優化建議

  1. 分片策略優化:根據數據特征選擇哈希分片或區間分片
  2. 批量處理:每次處理100-500條數據,避免大事務
  3. 異步執行:耗時操作放入線程池異步處理
  4. 索引優化:任務查詢的SQL必須走索引
  5. 日志精簡:關閉不必要的調試日志,保留關鍵操作日志

技術選型建議

  • 中小型項目:Spring Scheduler + Redis鎖
  • 大型分布式系統:Elastic-Job
  • 遺留系統改造:Quartz集群

最終解決方案沒有銀彈,根據團隊技術儲備和業務場景靈活選擇。建議從簡單方案入手,隨著業務發展逐步演進架構。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/73135.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/73135.shtml
英文地址,請注明出處:http://en.pswp.cn/web/73135.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MySQL 設置允許遠程連接完整指南:安全與效率并重

一、為什么需要遠程連接MySQL&#xff1f; 在分布式系統架構中&#xff0c;應用程序與數據庫往往部署在不同服務器。例如&#xff1a; Web服務器&#xff08;如NginxPHP&#xff09;需要連接獨立的MySQL數據庫數據分析師通過BI工具直連生產庫多服務器集群間的數據同步 但直接…

系統架構書單推薦(一)領域驅動設計與面向對象

本文主要是個人在學習過程中所涉獵的一些經典書籍&#xff0c;有些已經閱讀完&#xff0c;有些還在閱讀中。于我而言&#xff0c;希望追求軟件系統設計相關的原則、方法、思想、本質的東西&#xff0c;并希望通過不斷的學習、實踐和積累&#xff0c;提升自身的知識和認知。希望…

動態規劃-01背包

兜兜轉轉了半天&#xff0c;發現還是Carl寫的好。 看過動態規劃-基礎的讀者&#xff0c;大概都清楚。 動態規劃是將大問題&#xff0c;分解成子問題。并將子問題的解儲存下來&#xff0c;避免重復計算。 而背包問題&#xff0c;就是動態規劃延申出來的一個大類。 而01背包&…

使用VS2022編譯CEF

前提 選擇編譯的版本 CEF自動編譯&#xff0c;在這里可以看到最新的穩定版和Beta版。 從這里得出&#xff0c;最新的穩定版是134.0.6998.118&#xff0c;對應的cef branch是6998。通過這個信息可以在Build requirements查到相關的軟件配置信息。 這里主要看Windows下的編譯要…

C++20:玩轉 string 的 starts_with 和 ends_with

文章目錄 一、背景與動機二、string::starts_with 和 string::ends_with&#xff08;一&#xff09;語法與功能&#xff08;二&#xff09;使用示例1\. 判斷字符串開頭2\. 判斷字符串結尾 &#xff08;三&#xff09;優勢 三、string_view::starts_with 和 string_view::ends_w…

智能飛鳥監測 守護高壓線安全

飛鳥檢測新紀元&#xff1a;視覺分析技術的革新應用 在現代化社會中&#xff0c;飛鳥檢測成為了多個領域不可忽視的重要環節。無論是高壓線下的安全監測、工廠內的生產秩序維護&#xff0c;還是農業區的作物保護&#xff0c;飛鳥檢測都扮演著至關重要的角色。傳統的人工檢測方…

ADC噪聲全面分析 -04- 有效噪聲帶寬簡介

為什么要了解ENBW&#xff1f; 了解模數轉換器 (ADC) 噪聲可能具有挑戰性&#xff0c;即使對于最有經驗的模擬設計人員也是如此。 Delta-sigma ADC 具有量化和熱噪聲的組合&#xff0c;這取決于 ADC 的分辨率、參考電壓和輸出數據速率 (ODR)。 在系統級別&#xff0c;額外的信…

STM32單片機uCOS-Ⅲ系統10 內存管理

目錄 一、內存管理的基本概念 二、內存管理的運作機制 三、內存管理的應用場景 四、內存管理函數接口講解 1、內存池創建函數 OSMemCreate() 2、內存申請函數 OSMemGet() 3、內存釋放函數 OSMemPut() 五、實現 一、內存管理的基本概念 在計算系統中&#xff0c;變量、中…

考研課程安排(自用)

文章目錄 408數據結構&#xff08;王道&#xff09;計算機組成原理&#xff08;王道&#xff09;操作系統&#xff08;王道&#xff09;計算機網絡&#xff08;湖科大版&#xff09; 數學一高等數學&#xff08;微積分&#xff09;線性代數和概率論 408 數據結構&#xff08;王…

ultraiso制作u盤啟動

UltraISO制作U盤啟動盤的方法 UltraISO是一款功能強大的工具&#xff0c;可以幫助用戶將ISO鏡像文件寫入U盤&#xff0c;從而制作成可啟動的系統安裝盤。以下是詳細的步驟和注意事項&#xff1a; 1. ?準備工作? ?硬件準備?&#xff1a;一個容量至少為8GB的U盤&#xff0…

C語言-發布訂閱模式詳解與實踐

文章目錄 C語言發布訂閱模式詳解與實踐1. 什么是發布訂閱模式&#xff1f;2. 為什么需要發布訂閱模式&#xff1f;3. 實際應用場景4. 代碼實現4.1 UML 關系圖4.2 頭文件 (pubsub.h)4.3 實現文件 (pubsub.c)4.4 使用示例 (main.c) 5. 代碼分析5.1 關鍵設計點5.2 實現特點 6. 編譯…

藍橋杯2023年第十四屆省賽真題-異或和之差

題目來自DOTCPP&#xff1a; 思路&#xff1a; 什么是異或和&#xff1f; ①題目要求我們選擇兩個不相交的子段&#xff0c;我們可以枚舉一個分界線i&#xff0c;子段1在 i 的左邊&#xff0c; 子段2在 i 的右邊&#xff0c;分別找到子段1和子段2的最大值、最小值。 ②怎么確…

Linux作業2——有關文件系統權限的練習

1、創建/www目錄&#xff0c;在/www目錄下新建name和https目錄&#xff0c;在name和https目錄下分別創建一個index.html文件&#xff0c;name下面的index.html文件中包含當前主機的主機名&#xff0c;https目錄下的index.html文件中包含當前主機的ip地址。 #創建/www目錄&…

leeCode 70. 爬樓梯

假設你正在爬樓梯。需要 n 階你才能到達樓頂。 每次你可以爬 1 或 2 個臺階。你有多少種不同的方法可以爬到樓頂呢&#xff1f; 示例 1&#xff1a; 輸入&#xff1a;n 2 輸出&#xff1a;2 解釋&#xff1a;有兩種方法可以爬到樓頂。 1. 1 階 1 階 2. 2 階 示例 2&#x…

算法題(105):小貓爬山

審題&#xff1a; 本題需要我們找出將n個小貓放在有限重的纜車上運下山所需的最小纜車數 時間復雜度分析&#xff1a;本題的數據量小于等于18&#xff0c;所以我們在做好剪枝的前提下可以使用深度優先搜索解題 思路&#xff1a; 方法一&#xff1a;dfs 搜索策略&#xff1a;將小…

第十六章:Specialization and Overloading_《C++ Templates》notes

Specialization and Overloading 一、模板特化與重載的核心概念二、代碼實戰與測試用例三、關鍵知識點總結四、進階技巧五、實踐建議多選題設計題代碼測試說明 一、模板特化與重載的核心概念 函數模板重載 (Function Template Overloading) // 基礎模板 template<typename…

多協議兼容+高并發處理:EasyCVR如何破解AI安防規模化落地難題?

隨著AI技術在安防領域的深入應用&#xff0c;規模化部署面臨兩大核心挑戰&#xff1a;設備協議碎片化導致的接入壁壘與海量視頻流并發帶來的性能瓶頸。TSINGSEE青犀視頻的EasyCVR平臺通過“多協議兼容高并發處理”雙引擎驅動&#xff0c;結合云邊端協同架構與智能算法優化&…

IntelliJ IDEA 中 Git 高頻問題與操作詳解|新手避坑指南

標簽&#xff1a;IntelliJ IDEA Git操作, Git教程, 版本控制, 沖突解決, 分支管理 引言 你是否遇到過這些問題&#xff1f; 代碼提交后想撤銷怎么辦&#xff1f;合并分支時沖突不會解決&#xff1f;不小心把錯誤代碼推送到遠程倉庫&#xff1f; 本文針對 IntelliJ IDEA 中 Git …

【聊聊層次式架構設計:像搭樂高一樣構建軟件大廈】

文章目錄 聊聊層次式架構設計&#xff1a;像搭樂高一樣構建軟件大廈理論篇&#xff1a;層次式架構的“千層套路”最底層&#xff1a;基礎設施層——默默付出的“基石俠”數據訪問層&#xff1a;“數據快遞員”業務邏輯層&#xff1a;智慧的“大腦中樞”表示層&#xff1a;軟件的…

N列股票收盤價為起點的馬科維茨(Markowitz)均值—方差理論

1. 數據準備與收益率計算 輸入數據&#xff1a; 假設你有一個矩陣&#xff0c;每一列代表一只股票的歷史收盤價序列。每一行對應一個時間點的收盤價。 計算收益率&#xff1a; 馬科維茨理論要求使用資產的收益率而非價格。常用的收益率計算方法有對數收益率或簡單收益率。 2.…