最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Springboot使用Redis實現定時任務的三種方式

 更新時間:2025年06月25日 10:10:23   作者:weixin_43833540  
本文介紹了三種Redis定時任務實現方式,鍵空間通知,有序集合輪詢,分布式鎖,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

一、基于 Redis 鍵空間通知(適合精確延時任務)

原理:利用 Redis 的鍵過期事件(EXPIRE)觸發(fā)任務執(zhí)行,通過監(jiān)聽 __keyevent@*__:expired 通道捕獲事件。
步驟

啟用 Redis 鍵空間通知(redis.conf 或運行時配置):

CONFIG SET notify-keyspace-events Ex

Spring Boot 監(jiān)聽器實現

@Component
public class KeyExpiredListener extends KeyExpirationEventMessageListener {
    public KeyExpiredListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    @Override
    public void onMessage(Message message, byte[] pattern) {
        String expiredKey = new String(message.getBody());
        if (expiredKey.startsWith("task:")) { // 過濾業(yè)務鍵
            System.out.println("執(zhí)行任務: " + expiredKey);
            // 例如:task:123 過期時執(zhí)行訂單超時邏輯
        }
    }
}

注冊監(jiān)聽器

@Configuration
public class RedisConfig {
    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory factory, 
                                           KeyExpiredListener listener) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(factory);
        container.addMessageListener(listener, new PatternTopic("__keyevent@*__:expired"));
        return container;
    }
}

調度任務(設置帶過期時間的鍵):

@Service
public class TaskScheduler {
    @Autowired
    private StringRedisTemplate redisTemplate;

    public void scheduleTask(String taskId, long delaySeconds) {
        redisTemplate.opsForValue().set("task:" + taskId, "data", 
                delaySeconds, TimeUnit.SECONDS); // 鍵在 delaySeconds 秒后過期
    }
}

注意:需在 Redis 配置中開啟 notify-keyspace-events Ex。

二、基于 Redis 有序集合輪詢(適合批量定時任務)

原理:將任務執(zhí)行時間作為 ZSETscore,通過定時任務查詢到期的任務并執(zhí)行。
步驟

添加任務到 ZSET

public void addTask(String taskId, Instant executeTime) {
    stringRedisTemplate.opsForZSet().add("scheduled_tasks", taskId, 
          executeTime.getEpochSecond());
}

定時掃描并執(zhí)行任務(每分鐘輪詢):

@Scheduled(cron = "0 * * * * *") // 每分鐘執(zhí)行
public void pollTasks() {
    long now = Instant.now().getEpochSecond();
    Set<String> tasks = stringRedisTemplate.opsForZSet()
          .rangeByScore("scheduled_tasks", 0, now); // 獲取所有到期任務

    for (String task : tasks) {
        System.out.println("執(zhí)行任務: " + task);
        // 執(zhí)行后移除任務
        stringRedisTemplate.opsForZSet().remove("scheduled_tasks", task);
    }
}

優(yōu)點:避免鍵空間通知的丟失風險,適合任務量大的場景。

三、基于 Redis 分布式鎖(防集群任務重復執(zhí)行)

原理:在分布式環(huán)境中,通過 Redis 鎖確保同一時間只有一個實例執(zhí)行定時任務。
代碼示例

@Component
public class DistributedTask {
    @Autowired
    private StringRedisTemplate redisTemplate;
    private static final String LOCK_KEY = "TASK_LOCK:ORDER_CLEAN";

    @Scheduled(cron = "0 0 3 * * ?") // 每天凌晨3點執(zhí)行
    public void dailyTask() {
        Boolean locked = redisTemplate.opsForValue()
                .setIfAbsent(LOCK_KEY, "locked", Duration.ofMinutes(10));
        if (Boolean.TRUE.equals(locked)) {
            try {
                cleanExpiredOrders(); // 執(zhí)行核心任務
            } finally {
                redisTemplate.delete(LOCK_KEY); // 釋放鎖(可選)
            }
        }
    }
}

關鍵點

  • 使用 setIfAbsent 原子操作獲取鎖,避免并發(fā)沖突。
  • 鎖自動過期防止死鎖(如任務執(zhí)行超時)。

??版本要求??:
??Spring Data Redis ≥ 2.3.0??:該版本引入了 setIfAbsent(key, value, duration) 方法,支持??原子性設置鍵值+過期時間??(對應 Redis 的 SET key value NX EX seconds 命令)

四、方案對比

方案適用場景注意事項
鍵空間通知精確延時任務(如30分鐘后關單)需配置 Redis,事件可能丟失
有序集合輪詢批量任務、高可靠性場景需自行處理任務分頁和重試
分布式鎖集群環(huán)境防重復執(zhí)行(如日報生成)鎖超時時間需大于任務執(zhí)行時間

*補充:

  • 關鍵業(yè)務(如支付超時)建議結合 數據庫日志+重試機制 補償;
  • 高頻任務優(yōu)先選 ZSET 輪詢,避免鍵空間通知的性能瓶頸;
  • 分布式鎖的鎖鍵需包含業(yè)務標識(如 LOCK_KEY:業(yè)務名)。

到此這篇關于Springboot使用Redis實現定時任務的三種方式的文章就介紹到這了,更多相關Springboot Redis 定時任務內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家! 

相關文章

  • Spring框架十一種常見異常的解決方法匯總

    Spring框架十一種常見異常的解決方法匯總

    今天小編就為大家分享一篇關于Spring框架十一種常見異常的解決方法匯總,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • 如何在SpringBoot中使用logback優(yōu)化異常堆棧的輸出詳解

    如何在SpringBoot中使用logback優(yōu)化異常堆棧的輸出詳解

    最近項目中整合了logback,所以下面這篇文章主要給大家介紹了關于如何在SpringBoot中使用logback優(yōu)化異常堆棧的輸出,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-05-05
  • SpringBoot快速配置數據源的方法

    SpringBoot快速配置數據源的方法

    這篇文章主要介紹了SpringBoot快速配置數據源的方法,幫助大家更好的理解和使用springboot框架,感興趣的朋友可以了解下
    2020-10-10
  • springboot前后臺數據交互的示例代碼

    springboot前后臺數據交互的示例代碼

    這篇文章主要介紹了springboot前后臺數據交互的示例代碼,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • 圖解程序員必須掌握的Java常用8大排序算法

    圖解程序員必須掌握的Java常用8大排序算法

    本文以圖片與文字結合的方式講解了程序員必須掌握的Java常用8大排序算法:插入排序、冒泡排序、選擇排序、希爾排序 、快速排序、歸并排序、堆排序和LST基數排序,需要的朋友可以參考下
    2015-07-07
  • java如何實時動態(tài)獲取properties文件的內容

    java如何實時動態(tài)獲取properties文件的內容

    這篇文章主要介紹了java如何實時動態(tài)獲取properties文件的內容,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Dubbo新版本zk注冊中心連接問題及解決

    Dubbo新版本zk注冊中心連接問題及解決

    這篇文章主要介紹了Dubbo新版本zk注冊中心連接問題及解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • 淺談SpringMVC中Interceptor和Filter區(qū)別

    淺談SpringMVC中Interceptor和Filter區(qū)別

    這篇文章主要介紹了淺談SpringMVC中Interceptor和Filter區(qū)別,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-04-04
  • Java中枚舉類型的一種使用方式

    Java中枚舉類型的一種使用方式

    這篇文章主要介紹了Java中枚舉類型的一種使用方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-08-08
  • SpringBoot+Thymeleaf靜態(tài)資源的映射規(guī)則說明

    SpringBoot+Thymeleaf靜態(tài)資源的映射規(guī)則說明

    這篇文章主要介紹了SpringBoot+Thymeleaf靜態(tài)資源的映射規(guī)則說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11

最新評論

瑞金市| 阜阳市| 博客| 景谷| 渭南市| 丘北县| 台中县| 资溪县| 安宁市| 庆阳市| 保德县| 清水河县| 彰化县| 绵阳市| 鲜城| 佛坪县| 广灵县| 固镇县| 永川市| 独山县| 永兴县| 广宁县| 洛隆县| 治多县| 裕民县| 六枝特区| 乐平市| 宣城市| 阳谷县| 望江县| 莆田市| 阳高县| 大余县| 澄江县| 徐闻县| 临朐县| 江达县| 翁牛特旗| 上林县| 泰顺县| 静乐县|