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

springboot+redis監(jiān)聽過期Key實踐

 更新時間:2026年07月10日 14:42:41   作者:毅大師  
想知道如何用Redis輕松處理訂單超時自動取消?本文教你利用Redis鍵過期通知機(jī)制,無需復(fù)雜代碼即可監(jiān)控訂單有效期,通過配置Redis的keyspace notifications,結(jié)合Spring Boot,你能實時捕獲過期Key并自動執(zhí)行狀態(tài)更新,立即掌握這一高效技巧,提升業(yè)務(wù)穩(wěn)定性

前言

在訂單業(yè)務(wù)中,有時候需要對訂單設(shè)置有效期,有效期到了后如果還未支付,就需要修改訂單狀態(tài)。對于這種業(yè)務(wù)的實現(xiàn),有多種不同的辦法,比如:

1、使用Quartz,每次生成一個訂單,就創(chuàng)建一個定時任務(wù),到期后執(zhí)行業(yè)務(wù)代碼;

2、rabbitMq中的延遲隊列;

3、對Redis的Key進(jìn)行監(jiān)控;

 1、引入依賴

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

2、修改boot的redis配置

spring:
  #redis
  redis:
    database: 0
    host: 127.0.0.1
    password: redis_123456
    port: 6379

3、在服務(wù)器中

修改redis.conf配置文件(原來notify-keyspace-events 屬性是" " 空的,我們只需要填上“Ex”就行了)

notify-keyspace-events "Ex"

4、創(chuàng)建一個Redis監(jiān)控類

用于監(jiān)控過期的key,該類需繼承KeyExpirationEventMessageListener

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;

import java.nio.charset.StandardCharsets;

/**
 * @program: SpringCloud
 * @description: redis Key過期監(jiān)聽
 * @author: zhang yi
 * @create: 2020-03-24 14:14
 */
public class KeyExpiredListener extends KeyExpirationEventMessageListener {

    public KeyExpiredListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    @Override
    public void onMessage(Message message, byte[] pattern) {
        System.out.println("過期key:" + message.toString());
    }
}

5、創(chuàng)建Redis配置類

import com.zy.rabbitmq.base.Listener.KeyExpiredListener;
import org.springframework.beans.factory.annotation.Autowired;
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;

/**
 * @program: SpringCloud
 * @description: redis配置類
 * @author: zhang yi
 * @create: 2020-03-24 14:17
 */
@Configuration
public class RedisConfiguration {

    @Autowired
    private RedisConnectionFactory redisConnectionFactory;

    @Bean
    public RedisMessageListenerContainer redisMessageListenerContainer() {
        RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();
        redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory);
        return redisMessageListenerContainer;
    }

    @Bean
    public KeyExpiredListener keyExpiredListener() {
        return new KeyExpiredListener(this.redisMessageListenerContainer());
    }

}

6、這里提供一個redis工具類

用于存儲值,獲取值,獲取過期時間等操作。

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
/**
 * redis 工具類
 * @Author ZhangYi
 */
@Component
public class RedisUtil {

	@Resource
	private RedisTemplate<String, Object> redisTemplate;

	/**
	 * 指定緩存失效時間
	 * 
	 * @param key  鍵
	 * @param time 時間(秒)
	 * @return
	 */
	public boolean expire(String key, long time) {
		try {
			if (time > 0) {
				redisTemplate.expire(key, time, TimeUnit.SECONDS);
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * 根據(jù)key 獲取過期時間
	 * 
	 * @param key 鍵 不能為null
	 * @return 時間(秒) 返回0代表為永久有效
	 */
	public long getExpire(String key) {
		return redisTemplate.getExpire(key, TimeUnit.SECONDS);
	}

	/**
	 * 判斷key是否存在
	 * 
	 * @param key 鍵
	 * @return true 存在 false不存在
	 */
	public boolean hasKey(String key) {
		try {
			return redisTemplate.hasKey(key);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * 刪除緩存
	 * 
	 * @param key 可以傳一個值 或多個
	 */
	@SuppressWarnings("unchecked")
	public void del(String... key) {
		if (key != null && key.length > 0) {
			if (key.length == 1) {
				redisTemplate.delete(key[0]);
			} else {
				redisTemplate.delete(CollectionUtils.arrayToList(key));
			}
		}
	}

	// ============================String=============================
	/**
	 * 普通緩存獲取
	 * 
	 * @param key 鍵
	 * @return 值
	 */
	public Object get(String key) {
		return key == null ? null : redisTemplate.opsForValue().get(key);
	}

	/**
	 * 普通緩存放入
	 * 
	 * @param key   鍵
	 * @param value 值
	 * @return true成功 false失敗
	 */
	public boolean set(String key, Object value) {
		try {
			redisTemplate.opsForValue().set(key, value);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}

	}

	/**
	 * 普通緩存放入并設(shè)置時間
	 * 
	 * @param key   鍵
	 * @param value 值
	 * @param time  時間(秒) time要大于0 如果time小于等于0 將設(shè)置無限期
	 * @return true成功 false 失敗
	 */
	public boolean set(String key, Object value, long time) {
		try {
			if (time > 0) {
				redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
			} else {
				set(key, value);
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
}

7、測試

(這里開放兩個接口,一個set值,并設(shè)置過期時間為10秒,一個獲取值和過期時間,當(dāng)?shù)竭_(dá)過期時間,看是否回去到過期Key)

    @GetMapping("/put")
    public String demo(){
        redisUtil.set("name","zhangyi",10);
        return "aaa";
    }

    @GetMapping("/get")
    public Map<String,Object> get(){
        Map<String,Object> m =new HashMap<>();
        m.put("time",redisUtil.getExpire("name"));
        m.put("val",redisUtil.get("name"));
        return m;
    }

成功獲取到了過期Key,這里亂碼是因為boot集成的Redis存key或者value的時候,沒有配置字符串序列化。沒有配置的話是默認(rèn)使用jdk本身的序列化的。

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java四舍五入時保留指定小數(shù)位數(shù)的五種方式

    Java四舍五入時保留指定小數(shù)位數(shù)的五種方式

    這篇文章主要介紹了Java四舍五入時保留指定小數(shù)位數(shù)的五種方式,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-09-09
  • Spring Boot自定義錯誤視圖的方法詳解

    Spring Boot自定義錯誤視圖的方法詳解

    這篇文章主要介紹了Spring Boot自定義錯誤視圖的方法詳解,需要的朋友可以參考下
    2020-08-08
  • 在Web項目中手機(jī)短信驗證碼實現(xiàn)的全過程記錄

    在Web項目中手機(jī)短信驗證碼實現(xiàn)的全過程記錄

    這篇文章主要給大家介紹了關(guān)于在Web項目中實現(xiàn)短信驗證碼的全過程記錄,文中通過示例代碼介紹的非常詳細(xì),在文末跟大家提供了源碼下載,需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-12-12
  • java 單播、廣播、組播詳解及實例代碼

    java 單播、廣播、組播詳解及實例代碼

    這篇文章主要介紹了java 單播、廣播、組播詳解及實例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • Java進(jìn)階教程之String類

    Java進(jìn)階教程之String類

    這篇文章主要介紹了Java進(jìn)階教程之String類,String類對象是不可變對象(immutable object),String類是唯一一個不需要new關(guān)鍵字來創(chuàng)建對象的類,需要的朋友可以參考下
    2014-09-09
  • 線程池中使用spring aop事務(wù)增強(qiáng)

    線程池中使用spring aop事務(wù)增強(qiáng)

    這篇文章主要介紹了線程池中使用spring aop事務(wù)增強(qiáng),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-02-02
  • Spring Boot自定義Banner實現(xiàn)代碼

    Spring Boot自定義Banner實現(xiàn)代碼

    這篇文章主要介紹了Spring Boot自定義Banner實現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-01-01
  • idea如何開啟菜單欄

    idea如何開啟菜單欄

    文章介紹了如何通過修改IntelliJ IDEA的樣式文件`ui.lnf.xml`來重新顯示被關(guān)閉的菜單欄,并分享了解決問題的步驟
    2025-01-01
  • Java業(yè)務(wù)校驗工具實現(xiàn)方法

    Java業(yè)務(wù)校驗工具實現(xiàn)方法

    這篇文章主要介紹了Java業(yè)務(wù)校驗工具實現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • springboot上傳文件,url直接訪問資源問題

    springboot上傳文件,url直接訪問資源問題

    這篇文章主要介紹了springboot上傳文件,url直接訪問資源問題。具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11

最新評論

宜兰市| 卢氏县| 宁晋县| 乌拉特中旗| 丹东市| 顺昌县| 阿拉善左旗| 丰镇市| 高雄县| 铜川市| 长宁区| 临沧市| 偏关县| 孝昌县| 南溪县| 黔南| 元阳县| 福建省| 郑州市| 静乐县| 新源县| 济南市| 郑州市| 寿阳县| 石棉县| 潢川县| 嘉祥县| 中阳县| 九寨沟县| 林州市| 邵阳县| 屏南县| 山东| 建德市| 百色市| 景泰县| 米易县| 化隆| 获嘉县| 广德县| 溧水县|