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

springboot整合redis過(guò)期key監(jiān)聽(tīng)實(shí)現(xiàn)訂單過(guò)期的項(xiàng)目實(shí)踐

 更新時(shí)間:2023年12月21日 14:31:04   作者:一只牛博  
現(xiàn)在各種電商平臺(tái)都有自己的訂單過(guò)期時(shí)間設(shè)置,那么如何設(shè)置訂單時(shí)間過(guò)期呢,本文主要介紹了springboot整合redis過(guò)期key監(jiān)聽(tīng)實(shí)現(xiàn)訂單過(guò)期的項(xiàng)目實(shí)踐,感興趣的可以了解一下

業(yè)務(wù)場(chǎng)景說(shuō)明

對(duì)于訂單問(wèn)題,那些下單了但是沒(méi)有去支付的(占單情況),不管對(duì)于支付寶還是微信都有訂單的過(guò)期時(shí)間設(shè)置,但是對(duì)于我們自己維護(hù)的訂單呢。兩種方案:被動(dòng)修改,主動(dòng)修改。這里僅僅說(shuō)明對(duì)于主動(dòng)修改的監(jiān)聽(tīng)實(shí)現(xiàn)

修改redis的配置文件redis.conf(好像不改也可以)

image-20230409142704387

K:keyspace事件,事件以__keyspace@<db>__為前綴進(jìn)行發(fā)布;        
E:keyevent事件,事件以__keyevent@<db>__為前綴進(jìn)行發(fā)布;        
g:一般性的,非特定類(lèi)型的命令,比如del,expire,rename等;       
$:字符串特定命令;        
l:列表特定命令;        
s:集合特定命令;        
h:哈希特定命令;        
z:有序集合特定命令;        
x:過(guò)期事件,當(dāng)某個(gè)鍵過(guò)期并刪除時(shí)會(huì)產(chǎn)生該事件;        
e:驅(qū)逐事件,當(dāng)某個(gè)鍵因maxmemore策略而被刪除時(shí),產(chǎn)生該事件;        
A:g$lshzxe的別名,因此”AKE”意味著所有事件

pom依賴坐標(biāo)的引入

<!--版本號(hào)說(shuō)明。這里我使用的是<jedis.version>2.9.3</jedis.version>,<spring.boot.version>2.3.0.RELEASE</spring.boot.version>-->
<dependency>
  <groupId>redis.clients</groupId>
  <artifactId>jedis</artifactId>
  <version>${jedis.version}</version>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
  <version>${spring.boot.version}</version>
</dependency>

這里可能會(huì)存在的依賴沖突問(wèn)題是與io.netty

  • RedisConfig的配置

    package test.bo.work.config.redis;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.listener.RedisMessageListenerContainer;
    import redis.clients.jedis.JedisPool;
    import redis.clients.jedis.JedisPoolConfig;
    import test.bo.work.util.StringUtil;
    
    
    /**
     * @author xiaobo
     */
    @Configuration
    @EnableAutoConfiguration
    public class JedisConfig {
        private static final Logger LOGGER = LoggerFactory.getLogger(JedisConfig.class);
    
        @Value("${spring.redis.host}")
        private String host;
    
        @Value("${spring.redis.port}")
        private int port;
    
        @Value("${spring.redis.password}")
        private String password;
    
        @Value("${spring.redis.timeout}")
        private int timeout;
    
        @Value("${spring.redis.jedis.pool.max-active}")
        private int maxActive;
    
        @Value("${spring.redis.jedis.pool.max-wait}")
        private int maxWait;
    
        @Value("${spring.redis.jedis.pool.max-idle}")
        private int maxIdle;
    
        @Value("${spring.redis.jedis.pool.min-idle}")
        private int minIdle;
    
        @Bean
        public JedisPool redisPoolFactory() {
            try {
                JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
                jedisPoolConfig.setMaxIdle(maxIdle);
                jedisPoolConfig.setMaxWaitMillis(maxWait);
                jedisPoolConfig.setMaxTotal(maxActive);
                jedisPoolConfig.setMinIdle(minIdle);
                // JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, password);
                String pwd = StringUtil.isBlank(password) ? null : password;
                JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, pwd,6);
                LOGGER.info("初始化Redis連接池JedisPool成功!地址: " + host + ":" + port);
                return jedisPool;
            } catch (Exception e) {
                LOGGER.error("初始化Redis連接池JedisPool異常:" + e.getMessage());
            }
            return null;
        }
    
        @Bean
        public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
            RedisMessageListenerContainer container = new RedisMessageListenerContainer();
            container.setConnectionFactory(connectionFactory);
            return container;
        }
    
    
    }
    
  • 監(jiān)聽(tīng)器實(shí)現(xiàn)

    package test.bo.work.config.redis;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.data.redis.connection.Message;
    import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
    import org.springframework.data.redis.listener.PatternTopic;
    import org.springframework.data.redis.listener.RedisMessageListenerContainer;
    import org.springframework.stereotype.Component;
    
    import java.nio.charset.StandardCharsets;
    
    
    /**
     * @author xiaobo
     */
    @Component
    @Slf4j
    public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
    
      public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
        log.info("Redis Key Expiration Listener has been initialized.");
      }
    
      @Override
      public void onMessage(Message message, byte[] pattern) {
        String expiredKey = message.toString();
        log.error(expiredKey);
          // 判斷是否是想要監(jiān)聽(tīng)的過(guò)期key
          if (expiredKey.startsWith(KuoCaiConstants.ORDER_REDIS_PREFIX)) {
            // 根據(jù)過(guò)期redisKey獲取訂單號(hào)
            String transactionOrderId = expiredKey.substring(KuoCaiConstants.ORDER_REDIS_PREFIX.length());
            transactionOrderService.updateTransactionOrderStatusByRedis(Long.valueOf(transactionOrderId));
    }
      }
    }
    
    

    【注意】可能存在的問(wèn)題(監(jiān)聽(tīng)事件失效)

    【警告】存在的問(wèn)題

自己自定義了庫(kù),如下代碼

 @Override
    protected void doRegister(RedisMessageListenerContainer listenerContainer) {
        // 針對(duì)db6進(jìn)行監(jiān)聽(tīng)
        listenerContainer.addMessageListener(this, new PatternTopic("__keyevent@6__:expired"));
    }

這種情況,如果你存入的key不在db6,那么你就看不到監(jiān)聽(tīng)觸發(fā)事件(這里并不是失效,只是說(shuō)可能出現(xiàn)的你認(rèn)為失效的情況)

使用了默認(rèn)的連接工廠,但是配置文件中又沒(méi)有相關(guān)定義

首先解釋一下,默認(rèn)情況下,Spring Boot使用Jedis作為Redis客戶端,并且會(huì)自動(dòng)根據(jù)application.properties或application.yml配置文件中的spring.redis屬性來(lái)創(chuàng)建連接工廠。如果沒(méi)有指定這些屬性,則會(huì)使用默認(rèn)的localhost:6379作為Redis服務(wù)器地址。

如果你想要連接到其他的Redis服務(wù)器,可以在配置文件中設(shè)置spring.redis.hostspring.redis.port屬性來(lái)指定Redis服務(wù)器的地址和端口號(hào)。

image-20230409144000556

對(duì)于以上情況可以自定義工廠然后注入即可(上面的JedisConfig.java文件)

@Bean
public JedisConnectionFactory jedisConnectionFactory() {
  RedisStandaloneConfiguration redisStandaloneConfiguration =
    new RedisStandaloneConfiguration();
  redisStandaloneConfiguration.setHostName(host);
  redisStandaloneConfiguration.setDatabase(db);
  redisStandaloneConfiguration.setPassword(RedisPassword.of(password));
  redisStandaloneConfiguration.setPort(port);
  return new JedisConnectionFactory(redisStandaloneConfiguration);
}

@Bean
public RedisMessageListenerContainer container(JedisConnectionFactory jedisConnectionFactory) {
  RedisMessageListenerContainer container = new RedisMessageListenerContainer();
  container.setConnectionFactory(jedisConnectionFactory);
  return container;
}
  • Redis的Key事件通知機(jī)制默認(rèn)是異步的,即Redis會(huì)在Key過(guò)期時(shí)發(fā)送事件通知給所有監(jiān)聽(tīng)者,但是不能保證監(jiān)聽(tīng)者一定會(huì)及時(shí)接收到通知。如果您的應(yīng)用程序需要在Key過(guò)期后立即處理相關(guān)操作,可能需要使用其他方式來(lái)實(shí)現(xiàn)。

  • 在Redis中,Key的過(guò)期時(shí)間只是一個(gè)近似的時(shí)間,它并不是精確的,因此不能保證過(guò)期時(shí)間到達(dá)時(shí)就一定會(huì)立即過(guò)期。如果您需要在Key過(guò)期后立即處理相關(guān)操作,建議您使用其他方式來(lái)實(shí)現(xiàn),例如使用定時(shí)任務(wù)或輪詢方式檢查過(guò)期Key。

  • 在Redis中,Key的過(guò)期時(shí)間不能被取消或重置。如果您在設(shè)計(jì)時(shí)考慮到Key的過(guò)期時(shí)間可能需要修改,建議您使用其他方式來(lái)實(shí)現(xiàn)。

  • 當(dāng)Redis中的Key被持久化到磁盤(pán)上時(shí),過(guò)期時(shí)間可能會(huì)受到影響,因?yàn)檫^(guò)期時(shí)間的計(jì)算是基于系統(tǒng)時(shí)間的,如果系統(tǒng)時(shí)間發(fā)生變化,過(guò)期時(shí)間可能會(huì)出現(xiàn)不準(zhǔn)確的情況。因此,建議您使用其他方式來(lái)處理需要精確過(guò)期時(shí)間的場(chǎng)景。

到此這篇關(guān)于springboot整合redis過(guò)期key監(jiān)聽(tīng)實(shí)現(xiàn)訂單過(guò)期的項(xiàng)目實(shí)踐的文章就介紹到這了,更多相關(guān)springboot redis過(guò)期key監(jiān)聽(tīng)訂單過(guò)期內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot讀取配置的6種方式

    SpringBoot讀取配置的6種方式

    本文主要介紹了SpringBoot讀取配置的6種方式,主要包括使用默認(rèn)配置、使用application.properties文件、使用application.yml文件、使用@Value注解、使用Environment對(duì)象和使用ConfigurableEnvironment對(duì)象,感興趣的可以了解一下
    2023-08-08
  • Java編程中的equals方法使用全解

    Java編程中的equals方法使用全解

    這篇文章主要介紹了Java編程中的equals方法使用全解,是Java入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-10-10
  • Java解壓和壓縮帶密碼的zip文件過(guò)程詳解

    Java解壓和壓縮帶密碼的zip文件過(guò)程詳解

    這篇文章主要介紹了Java解壓和壓縮帶密碼的zip文件,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,下面我們來(lái)學(xué)習(xí)一下吧
    2019-06-06
  • redis實(shí)現(xiàn)多進(jìn)程數(shù)據(jù)同步工具代碼分享

    redis實(shí)現(xiàn)多進(jìn)程數(shù)據(jù)同步工具代碼分享

    這篇文章主要介紹了使用redis實(shí)現(xiàn)多進(jìn)程數(shù)據(jù)同步工具的代碼,大家參考使用吧
    2014-01-01
  • Java 設(shè)計(jì)模式之適配器模式詳解

    Java 設(shè)計(jì)模式之適配器模式詳解

    設(shè)計(jì)模式(Design pattern)是一套被反復(fù)使用、多數(shù)人知曉的、經(jīng)過(guò)分類(lèi)編目的、代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)。使用設(shè)計(jì)模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性
    2021-11-11
  • Java解析方法的調(diào)用關(guān)系示例詳解

    Java解析方法的調(diào)用關(guān)系示例詳解

    這篇文章主要介紹了Java解析方法的調(diào)用關(guān)系,方法在Java編程中用于封裝重復(fù)的代碼,提高代碼復(fù)用性,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-10-10
  • 記一次公司JVM堆溢出抽絲剝繭定位的過(guò)程解析

    記一次公司JVM堆溢出抽絲剝繭定位的過(guò)程解析

    這篇文章主要介紹了記一次公司JVM堆溢出抽絲剝繭定位的過(guò)程,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • Java調(diào)用CMD命令的方法與使用技巧

    Java調(diào)用CMD命令的方法與使用技巧

    在實(shí)際的開(kāi)發(fā)中我們有可能會(huì)遇到?java調(diào)用?cmd命令的情況,這篇文章主要給大家介紹了關(guān)于Java調(diào)用CMD命令的方法與使用的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-09-09
  • MyBatis?Plus?導(dǎo)入IdType失敗的解決

    MyBatis?Plus?導(dǎo)入IdType失敗的解決

    這篇文章主要介紹了MyBatis?Plus?導(dǎo)入IdType失敗的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • mybatis trim標(biāo)簽的使用詳解

    mybatis trim標(biāo)簽的使用詳解

    這篇文章主要介紹了mybatis trim標(biāo)簽的使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06

最新評(píng)論

汨罗市| 左贡县| 渭南市| 垣曲县| 沂南县| 西乡县| 遂平县| 肇庆市| 仙桃市| 祁阳县| 许昌县| 惠安县| 沈阳市| 临汾市| 永宁县| 资中县| 博爱县| 磴口县| 潞城市| 墨脱县| 安阳县| 绥棱县| 灵武市| 揭阳市| 公主岭市| 法库县| 华池县| 玛沁县| 张家界市| 阜宁县| 宜兰市| 德江县| 荆州市| 中西区| 阜城县| 菏泽市| 称多县| 澳门| 黎城县| 南部县| 康马县|