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

SpringBoot中Redisson延遲隊(duì)列的示例

 更新時(shí)間:2024年10月16日 09:28:39   作者:Frank-fu  
延時(shí)隊(duì)列是一種常見(jiàn)的需求,延時(shí)隊(duì)列允許我們延遲處理某些任務(wù),本文主要介紹了Redisson延遲隊(duì)列的示例,具有一定的參考價(jià)值,感興趣的可以了解一下

場(chǎng)景:

需求:

支付的二維碼,超過(guò)兩個(gè)小時(shí)以后,如果還未支付,則自動(dòng)轉(zhuǎn)為取消支付,或者支付超時(shí)的狀態(tài)

需求分析:

1,動(dòng)態(tài)定時(shí)任務(wù):

每個(gè)支付的二維碼創(chuàng)建的時(shí)候,創(chuàng)建一個(gè)動(dòng)態(tài)的定時(shí)任務(wù),兩個(gè)小時(shí)候自動(dòng)執(zhí)行,更新支付狀態(tài),可以解決這個(gè)問(wèn)題。

(1)持久化:

如果服務(wù)重啟了,動(dòng)態(tài)定時(shí)任務(wù)會(huì)丟失,導(dǎo)致部分?jǐn)?shù)據(jù)沒(méi)辦法更新?tīng)顟B(tài)。

(2)分布式:

如果當(dāng)服務(wù)重啟時(shí),自動(dòng)掃描數(shù)據(jù),重新計(jì)算時(shí)間,再次創(chuàng)建動(dòng)態(tài)定時(shí)任務(wù)??梢越鉀Q(1)的問(wèn)題,但是當(dāng)分布式,多個(gè)節(jié)點(diǎn)的時(shí)候,都會(huì)重新加載所有的任務(wù),這樣性能上不是最優(yōu)解,只能在數(shù)據(jù)源上加上節(jié)點(diǎn)名稱,不同的服務(wù)節(jié)點(diǎn),加載屬于自己的定時(shí)任務(wù),可以解決這個(gè)問(wèn)題。總的想想,太麻煩了,還是算了。

2,Redisson延遲隊(duì)列

(1)持久化:隊(duì)列信息放在Redis上,服務(wù)重啟不影響。

(2)分布式:多節(jié)點(diǎn)去Redis拿去數(shù)據(jù),誰(shuí)搶到算誰(shuí)的,不會(huì)存在同一個(gè)任務(wù),多個(gè)節(jié)點(diǎn)支持。唯一不足就是過(guò)度依賴Redis,萬(wàn)一Redis崩了,那就涼涼了(那就是要把Redis配置高可用,當(dāng)前業(yè)務(wù)就不用管了)。總體來(lái)說(shuō)還是比較好用的。

實(shí)現(xiàn)

1,創(chuàng)建延遲隊(duì)列的監(jiān)聽(tīng)任務(wù)【RedisDelayedQueueListener】,消費(fèi)延遲隊(duì)列

2,創(chuàng)建新增延遲隊(duì)列的類(lèi),用于創(chuàng)建延遲隊(duì)列

3,整體初始化,把監(jiān)聽(tīng)任務(wù)與spring綁定,掃描各個(gè)監(jiān)聽(tīng)延遲隊(duì)列的實(shí)現(xiàn)類(lèi),并開(kāi)啟單獨(dú)線程,監(jiān)聽(tīng)任務(wù)。

4,創(chuàng)建延遲任務(wù)(開(kāi)始測(cè)試使用)

連接Redis

不貼代碼了,自己在網(wǎng)上搜

監(jiān)聽(tīng)延遲隊(duì)列

接口:

/**
 * 隊(duì)列事件監(jiān)聽(tīng)接口,需要實(shí)現(xiàn)這個(gè)方法
 *
 * @module
 * @author frank
 * @date 2021/8/19 10:50
 */
public interface RedisDelayedQueueListener<T> {
    /**
     * 執(zhí)行方法
     *
     * @param t
     */
    void invoke(T t);
}

實(shí)現(xiàn):

import com.sxmaps.netschool.common.redisson.RedisDelayedQueueListener;
import com.sxmaps.netschool.service.vo.school.SchoolAccountPayStateReqVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 支付二維碼監(jiān)聽(tīng)器
 *
 * @module
 * @author frank
 * @date 2021/8/19 10:49
 */
@Component
public class PayQCordListener implements RedisDelayedQueueListener<SchoolAccountPayStateReqVO> {

    private final Logger logger = LoggerFactory.getLogger(PayQCordListener.class);
    @Autowired
    private SchoolAccountService schoolAccountService;

    @Override
    public void invoke(SchoolAccountPayStateReqVO payStateReqVO) {
        logger.info("支付二維碼-延遲失效,內(nèi)容:{}", payStateReqVO);
         //處理業(yè)務(wù),更新二維碼狀態(tài)
        logger.info("支付二維碼-延遲失效,內(nèi)容:{},處理結(jié)果:{}", payStateReqVO,respDTO);
    }
}

增加延遲隊(duì)列

import org.redisson.api.RBlockingQueue;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * 增加延遲信息
 *
 * @author frank
 * @module
 * @date 2021/8/19 10:49
 */
@Component
public class RedisDelayedQueue {

    private final Logger logger = LoggerFactory.getLogger(RedisDelayedQueue.class);

    @Autowired
    RedissonClient redissonClient;

    /**
     * 添加隊(duì)列
     *
     * @param t        DTO傳輸類(lèi)
     * @param delay    時(shí)間數(shù)量
     * @param timeUnit 時(shí)間單位
     * @param <T>      泛型
     */
    private <T> void addQueue(T t, long delay, TimeUnit timeUnit, String queueName) {
        logger.info("添加延遲隊(duì)列,監(jiān)聽(tīng)名稱:{},時(shí)間:{},時(shí)間單位:{},內(nèi)容:{}" , queueName, delay, timeUnit,t);
        RBlockingQueue<T> blockingFairQueue = redissonClient.getBlockingQueue(queueName);
        RDelayedQueue<T> delayedQueue = redissonClient.getDelayedQueue(blockingFairQueue);
        delayedQueue.offer(t, delay, timeUnit);
    }

    /**
     * 添加隊(duì)列-秒
     *
     * @param t     DTO傳輸類(lèi)
     * @param delay 時(shí)間數(shù)量
     * @param <T>   泛型
     */
    public <T> void addQueueSeconds(T t, long delay, Class<? extends RedisDelayedQueueListener> clazz) {
        addQueue(t, delay, TimeUnit.SECONDS, clazz.getName());
    }

    /**
     * 添加隊(duì)列-分
     *
     * @param t     DTO傳輸類(lèi)
     * @param delay 時(shí)間數(shù)量
     * @param <T>   泛型
     */
    public <T> void addQueueMinutes(T t, long delay, Class<? extends RedisDelayedQueueListener> clazz) {
        addQueue(t, delay, TimeUnit.MINUTES, clazz.getName());
    }

    /**
     * 添加隊(duì)列-時(shí)
     *
     * @param t     DTO傳輸類(lèi)
     * @param delay 時(shí)間數(shù)量
     * @param <T>   泛型
     */
    public <T> void addQueueHours(T t, long delay, Class<? extends RedisDelayedQueueListener> clazz) {
        addQueue(t, delay, TimeUnit.HOURS, clazz.getName());
    }
    /**
     * 添加隊(duì)列-天
     *
     * @param t     DTO傳輸類(lèi)
     * @param delay 時(shí)間數(shù)量
     * @param <T>   泛型
     */
    public <T> void addQueueDays(T t, long delay, Class<? extends RedisDelayedQueueListener> clazz) {
        addQueue(t, delay, TimeUnit.DAYS, clazz.getName());
    }
}

整體初始化

import org.redisson.api.RBlockingQueue;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * 初始化隊(duì)列監(jiān)聽(tīng)
 *
 * @module
 * @author frank
 * @date 2021/8/19 10:49
 */
@Component
public class RedisDelayedQueueInit implements ApplicationContextAware {

    private final Logger logger = LoggerFactory.getLogger(RedisDelayedQueueInit.class);
    @Autowired
    RedissonClient redissonClient;

    /**
     * 獲取應(yīng)用上下文并獲取相應(yīng)的接口實(shí)現(xiàn)類(lèi)
     *
     * @param applicationContext
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        Map<String, RedisDelayedQueueListener> map = applicationContext.getBeansOfType(RedisDelayedQueueListener.class);
        for (Map.Entry<String, RedisDelayedQueueListener> taskEventListenerEntry : map.entrySet()) {
            String listenerName = taskEventListenerEntry.getValue().getClass().getName();
            startThread(listenerName, taskEventListenerEntry.getValue());
        }
    }

    /**
     * 啟動(dòng)線程獲取隊(duì)列*
     *
     * @param queueName                 queueName
     * @param redisDelayedQueueListener 任務(wù)回調(diào)監(jiān)聽(tīng)
     * @param <T>                       泛型
     * @return
     */
    private <T> void startThread(String queueName, RedisDelayedQueueListener redisDelayedQueueListener) {
        RBlockingQueue<T> blockingFairQueue = redissonClient.getBlockingQueue(queueName);
        //服務(wù)重啟后,無(wú)offer,take不到信息。
        redissonClient.getDelayedQueue(blockingFairQueue);
        //由于此線程需要常駐,可以新建線程,不用交給線程池管理
        Thread thread = new Thread(() -> {
            logger.info("啟動(dòng)監(jiān)聽(tīng)隊(duì)列線程" + queueName);
            while (true) {
                try {
                    T t = blockingFairQueue.take();
                    logger.info("監(jiān)聽(tīng)隊(duì)列線程,監(jiān)聽(tīng)名稱:{},內(nèi)容:{}", queueName, t);
                    redisDelayedQueueListener.invoke(t);
                } catch (Exception e) {
                    logger.info("監(jiān)聽(tīng)隊(duì)列線程錯(cuò)誤,", e);
                }
            }
        });
        thread.setName(queueName);
        thread.start();
    }

}

創(chuàng)建延遲任務(wù)

@Autowired
RedisDelayedQueue queue;
.................

queue.addQueueHours(new SchoolAccountPayStateReqVO(dto.getPayNo()),2, PayQCordListener.class);

到此這篇關(guān)于Redisson延遲隊(duì)列的示例的文章就介紹到這了,更多相關(guān)Redisson延遲隊(duì)列內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 淺談Java高并發(fā)解決方案以及高負(fù)載優(yōu)化方法

    淺談Java高并發(fā)解決方案以及高負(fù)載優(yōu)化方法

    這篇文章主要介紹了淺談Java高并發(fā)解決方案以及高負(fù)載優(yōu)化方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • 手把手教你如何在idea中搭建SpringBoot項(xiàng)目

    手把手教你如何在idea中搭建SpringBoot項(xiàng)目

    這篇文章主要介紹了如何搭建一個(gè)SpringBoot項(xiàng)目,包括環(huán)境準(zhǔn)備、創(chuàng)建新項(xiàng)目、探索項(xiàng)目結(jié)構(gòu)以及展望未來(lái),通過(guò)詳細(xì)的步驟和實(shí)用的技巧,幫助開(kāi)發(fā)者快速上手SpringBoot開(kāi)發(fā),文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2025-02-02
  • 使用@ControllerAdvice同時(shí)配置過(guò)濾多個(gè)包

    使用@ControllerAdvice同時(shí)配置過(guò)濾多個(gè)包

    這篇文章主要介紹了使用@ControllerAdvice同時(shí)配置過(guò)濾多個(gè)包的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • AndroidQ沙盒機(jī)制之分區(qū)存儲(chǔ)適配

    AndroidQ沙盒機(jī)制之分區(qū)存儲(chǔ)適配

    這篇文章主要介紹了AndroidQ沙盒機(jī)制之分區(qū)存儲(chǔ)適配,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • SpringBoot攔截器的使用小結(jié)

    SpringBoot攔截器的使用小結(jié)

    今天給大家總結(jié)一下SpringBoot下攔截器的使用,需要的朋友參考下吧
    2017-05-05
  • SpringBoot使用jsoup爬取HTML的方法

    SpringBoot使用jsoup爬取HTML的方法

    jsoup 是一款 Java 的 HTML 解析器,它提供了一套非常便利的 API,可通過(guò) DOM、CSS 通過(guò)類(lèi)似于 JQuery 的操作方法來(lái)取出和操作數(shù)據(jù),這篇文章主要介紹了SpringBoot使用jsoup爬取HTML,需要的朋友可以參考下
    2024-02-02
  • SpringBoot的@Value給靜態(tài)變量注入application.properties屬性值

    SpringBoot的@Value給靜態(tài)變量注入application.properties屬性值

    這篇文章主要介紹了SpringBoot的@Value給靜態(tài)變量注入application.properties屬性值,Spring是一個(gè)開(kāi)源的框架,主要是用來(lái)簡(jiǎn)化開(kāi)發(fā)流程,通過(guò)IOC,依賴注入(DI)和面向接口實(shí)現(xiàn)松耦合,需要的朋友可以參考下
    2023-05-05
  • Springboot 如何實(shí)現(xiàn)filter攔截token驗(yàn)證和跨域

    Springboot 如何實(shí)現(xiàn)filter攔截token驗(yàn)證和跨域

    這篇文章主要介紹了Springboot 如何實(shí)現(xiàn)filter攔截token驗(yàn)證和跨域操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java代碼實(shí)現(xiàn)發(fā)送QQ和網(wǎng)易電子郵件

    Java代碼實(shí)現(xiàn)發(fā)送QQ和網(wǎng)易電子郵件

    這篇文章主要為大家詳細(xì)介紹了如何通過(guò)Java代碼實(shí)現(xiàn)發(fā)送QQ和網(wǎng)易電子郵件功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2026-02-02
  • Java 實(shí)現(xiàn)簡(jiǎn)單Socket 通信的示例

    Java 實(shí)現(xiàn)簡(jiǎn)單Socket 通信的示例

    這篇文章主要介紹了Java 實(shí)現(xiàn)簡(jiǎn)單Socket 通信的示例,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下
    2021-03-03

最新評(píng)論

余庆县| 台湾省| 纳雍县| 通州市| 定远县| 措勤县| 赣州市| 广宁县| 新余市| 湖口县| 西畴县| 潜山县| 和平县| 宣威市| 新疆| 绥芬河市| 乌什县| 庆云县| 新泰市| 外汇| 句容市| 兰考县| 都兰县| 仁化县| 深州市| 浮梁县| 沁阳市| 定南县| 富裕县| 泗阳县| 双江| 祁东县| 永和县| 连江县| 开封市| 铁岭县| 德阳市| 祁阳县| 彭州市| 凯里市| 罗甸县|