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

Redis集群下過(guò)期key監(jiān)聽(tīng)的實(shí)現(xiàn)代碼

 更新時(shí)間:2019年09月09日 13:09:54   作者:超人小冰  
這篇文章主要介紹了Redis集群下過(guò)期key監(jiān)聽(tīng)的實(shí)現(xiàn)代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

1. 前言

在使用redis集群時(shí),發(fā)現(xiàn)過(guò)期key始終監(jiān)聽(tīng)不到。網(wǎng)上也沒(méi)有現(xiàn)成的解決方案。于是想,既然不能監(jiān)聽(tīng)集群,那我可以建立多個(gè)redis連接,分別對(duì)每個(gè)redis的key過(guò)期進(jìn)行監(jiān)聽(tīng)。以上做法可能不盡人意,目前也沒(méi)找到好的解決方案,如果有好的想法,請(qǐng)留言告知哦!不多說(shuō),直接貼我自己的代碼!

2. 代碼實(shí)現(xiàn)

關(guān)于Redis集群配置代碼此處不貼,直接貼配置監(jiān)聽(tīng)類(lèi)代碼!

redis.host1: 10.113.56.68
redis.port1: 7030
redis.host2: 10.113.56.68
redis.port2: 7031
redis.host3: 10.113.56.68
redis.port3: 7032
redis.host4: 10.113.56.68
redis.port4: 7033
redis.host5: 10.113.56.68
redis.port5: 7034
redis.host6: 10.113.56.68
redis.port6: 7035
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolConfig;

import java.util.Arrays;

/**
 * @Author xiabing5
 * @Create 2019/8/6 14:46
 * @Desc  監(jiān)聽(tīng)redis中Key過(guò)期事件
 **/
@Configuration
public class RedisListenerConfig {

  @Value("${redis.host1}")
  private String host1;

  @Value("${redis.host2}")
  private String host2;

  @Value("${redis.host3}")
  private String host3;

  @Value("${redis.host4}")
  private String host4;

  @Value("${redis.host5}")
  private String host5;

  @Value("${redis.host6}")
  private String host6;

  @Value("${redis.port1}")
  private int port1;

  @Value("${redis.port2}")
  private int port2;

  @Value("${redis.port3}")
  private int port3;

  @Value("${redis.port4}")
  private int port4;

  @Value("${redis.port5}")
  private int port5;

  @Value("${redis.port6}")
  private int port6;

  @Bean
  JedisPoolConfig jedisPoolConfig(){
    JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
    jedisPoolConfig.setMaxIdle(100);
    jedisPoolConfig.setMaxWaitMillis(1000);
    return jedisPoolConfig;
  }

  // redis-cluster不支持key過(guò)期監(jiān)聽(tīng),建立多個(gè)連接,對(duì)每個(gè)redis節(jié)點(diǎn)進(jìn)行監(jiān)聽(tīng)
  @Bean
  RedisMessageListenerContainer redisContainer1() {
    final RedisMessageListenerContainer container = new RedisMessageListenerContainer();
    JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
    jedisConnectionFactory.setHostName(host1);
    jedisConnectionFactory.setPort(port1);
    jedisConnectionFactory.setPoolConfig(jedisPoolConfig());
    jedisConnectionFactory.afterPropertiesSet();
    container.setConnectionFactory(jedisConnectionFactory);
    return container;
  }

  @Bean
  RedisMessageListenerContainer redisContainer2() {
    final RedisMessageListenerContainer container = new RedisMessageListenerContainer();
    JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
    jedisConnectionFactory.setHostName(host2);
    jedisConnectionFactory.setPort(port2);
    jedisConnectionFactory.setPoolConfig(jedisPoolConfig());
    jedisConnectionFactory.afterPropertiesSet();
    container.setConnectionFactory(jedisConnectionFactory);
    return container;
  }

  @Bean
  RedisMessageListenerContainer redisContainer3() {
    final RedisMessageListenerContainer container = new RedisMessageListenerContainer();
    JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
    jedisConnectionFactory.setHostName(host3);
    jedisConnectionFactory.setPort(port3);
    jedisConnectionFactory.setPoolConfig(jedisPoolConfig());
    jedisConnectionFactory.afterPropertiesSet();
    container.setConnectionFactory(jedisConnectionFactory);
    return container;
  }

  @Bean
  RedisMessageListenerContainer redisContainer4() {
    final RedisMessageListenerContainer container = new RedisMessageListenerContainer();
    JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
    jedisConnectionFactory.setHostName(host4);
    jedisConnectionFactory.setPort(port4);
    jedisConnectionFactory.setPoolConfig(jedisPoolConfig());
    jedisConnectionFactory.afterPropertiesSet();
    container.setConnectionFactory(jedisConnectionFactory);
    return container;
  }

  @Bean
  RedisMessageListenerContainer redisContainer5() {
    final RedisMessageListenerContainer container = new RedisMessageListenerContainer();
    JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
    jedisConnectionFactory.setHostName(host5);
    jedisConnectionFactory.setPort(port5);
    jedisConnectionFactory.setPoolConfig(jedisPoolConfig());
    jedisConnectionFactory.afterPropertiesSet();
    container.setConnectionFactory(jedisConnectionFactory);
    return container;
  }

  @Bean
  RedisMessageListenerContainer redisContainer6() {
    final RedisMessageListenerContainer container = new RedisMessageListenerContainer();
    JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
    jedisConnectionFactory.setHostName(host6);
    jedisConnectionFactory.setPort(port6);
    jedisConnectionFactory.setPoolConfig(jedisPoolConfig());
    jedisConnectionFactory.afterPropertiesSet();
    container.setConnectionFactory(jedisConnectionFactory);
    return container;
  }

  @Bean
  RedisKeyExpirationListener redisKeyExpirationListener1() {
    return new RedisKeyExpirationListener(redisContainer1());
  }

  @Bean
  RedisKeyExpirationListener redisKeyExpirationListener2() {
    return new RedisKeyExpirationListener(redisContainer2());
  }

  @Bean
  RedisKeyExpirationListener redisKeyExpirationListener3() {
    return new RedisKeyExpirationListener(redisContainer3());
  }

  @Bean
  RedisKeyExpirationListener redisKeyExpirationListener4() {
    return new RedisKeyExpirationListener(redisContainer4());
  }

  @Bean
  RedisKeyExpirationListener redisKeyExpirationListener5() {
    return new RedisKeyExpirationListener(redisContainer5());
  }

  @Bean
  RedisKeyExpirationListener redisKeyExpirationListener6() {
    return new RedisKeyExpirationListener(redisContainer6());
  }

}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import java.util.Date;

/**
 * @Author xiabing5
 * @Create 2019/9/4 9:47
 * @Desc  redis過(guò)期監(jiān)聽(tīng)
 **/
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
  @Autowired
  RedisUtil redisUtil;
  @Autowired
  LoginUserStatisticsMapper loginUserStatisticsMapper;
  public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
    super(listenerContainer);
  }
  @Override
  public void onMessage(Message message, byte[] pattern) {
    // 用戶做自己的業(yè)務(wù)處理即可,message.toString()可以獲取失效的key
    String mesg = message.toString();   
  }
}

3. Redis防止過(guò)期key重復(fù)監(jiān)聽(tīng)

對(duì)于項(xiàng)目集群情況下,部署多個(gè)服務(wù)后,容易出現(xiàn)redis過(guò)期被多個(gè)服務(wù)同時(shí)監(jiān)聽(tīng)到,從而執(zhí)行相同的業(yè)務(wù)邏輯,這不是我們期望的。單機(jī)部署下方法的同步可以采用synchronize關(guān)鍵字。但集群下,就得采用分布式鎖。在需要加鎖的地方,只要加鎖和解鎖即可。此處正好寫(xiě)到Redis,那就貼一個(gè)自己用的redis分布式鎖。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import java.util.Collections;
import java.util.UUID;
/**
 * @Author xiabing5
 * @Create 2019/9/6 15:54
 * @Desc  redis分布式鎖
 **/
@Component
public class RedisLock {
  @Autowired
  Jedis jedis;
  private static final String SET_IF_NOT_EXIST = "NX"; // NX表示如果不存在key就設(shè)置value
  private static final String SET_WITH_EXPIRE_TIME = "PX"; // PX表示毫秒
  // 加鎖
  public String tryLock(String key,Long acquireTimeout) {
    // 生成隨機(jī)value
    String identifierValue = UUID.randomUUID().toString();
    // 設(shè)置超時(shí)時(shí)間
    Long endTime = System.currentTimeMillis() + acquireTimeout;
    // 循環(huán)獲取鎖
    while (System.currentTimeMillis() < endTime) {
      String result = jedis.set(key,identifierValue, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, acquireTimeout);
      if("OK".equals(result)) {
        return identifierValue;
      }
    }
    return null;
  }
  // 解鎖
//  public void delLock(String key,String identifierValue) {
//    // 判斷是否是同一把鎖
//    try{
//      if(jedis.get(key).equals(identifierValue)){
//        // 此處操作非原子性,容易造成釋放非自己的鎖
//        jedis.del(key);
//      }
//    }catch(Exception e) {
//      e.printStackTrace();
//    }
//  }
  // 使用Lua代碼解鎖
  public void delLock(String key,String identifierValue) {
    try{
      String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
      Long result = (Long) jedis.eval(script, Collections.singletonList(key), Collections.singletonList(identifierValue));
      if (1 == result) {
        System.out.println(result+"釋放鎖成功");
      } if (0 == result) {
        System.out.println(result+"釋放鎖失敗");
      }
    }catch (Exception e) {
      e.printStackTrace();
    }
  }
}

4. 總結(jié)

自己實(shí)現(xiàn)的一個(gè)小demo,廢話比較少。小白自己寫(xiě)的配置類(lèi),理解有問(wèn)題請(qǐng)留言!自己實(shí)現(xiàn)的方案感覺(jué)不妥,只是基本完成需求,還得繼續(xù)研究。

以上所述是小編給大家介紹的Redis集群下過(guò)期key監(jiān)聽(tīng)的實(shí)現(xiàn)代碼,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺(jué)得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!

相關(guān)文章

  • redis lettuce連接池經(jīng)常出現(xiàn)連接拒絕(Connection refused)問(wèn)題解決

    redis lettuce連接池經(jīng)常出現(xiàn)連接拒絕(Connection refused)問(wèn)題解決

    本文主要介紹了在Windows 10/11系統(tǒng)中使用Spring Boot和Lettuce連接池訪問(wèn)Redis時(shí),遇到的連接拒絕問(wèn)題,下面就來(lái)介紹一下解決方法,感興趣的可以了解一下
    2025-03-03
  • 關(guān)于Redis庫(kù)存超賣(mài)問(wèn)題的分析

    關(guān)于Redis庫(kù)存超賣(mài)問(wèn)題的分析

    在高并發(fā)場(chǎng)景下進(jìn)行優(yōu)惠券秒殺測(cè)試時(shí),發(fā)現(xiàn)由于并發(fā)操作導(dǎo)致了超賣(mài)問(wèn)題,即理論上只能賣(mài)出100個(gè)優(yōu)惠券,實(shí)際賣(mài)出了102個(gè),分析原因,是因?yàn)樵诟卟l(fā)環(huán)境下,多個(gè)線程同時(shí)操作庫(kù)存,導(dǎo)致數(shù)據(jù)不一致,提出了兩種解決方案:悲觀鎖和樂(lè)觀鎖
    2024-11-11
  • Redis底層數(shù)據(jù)結(jié)構(gòu)之dict、ziplist、quicklist詳解

    Redis底層數(shù)據(jù)結(jié)構(gòu)之dict、ziplist、quicklist詳解

    本文給大家詳細(xì)介紹了Redis的底層數(shù)據(jù)結(jié)構(gòu):dict、ziplist、quicklist的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2021-09-09
  • 淺談分布式鎖的幾種使用方式(redis、zookeeper、數(shù)據(jù)庫(kù))

    淺談分布式鎖的幾種使用方式(redis、zookeeper、數(shù)據(jù)庫(kù))

    這篇文章主要介紹了淺談分布式鎖的幾種使用方式(redis、zookeeper、數(shù)據(jù)庫(kù)),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • Redis不僅僅是緩存,還是……

    Redis不僅僅是緩存,還是……

    Redis是一個(gè)開(kāi)源的(BSD協(xié)議),內(nèi)存中的數(shù)據(jù)結(jié)構(gòu)存儲(chǔ),它可以用作數(shù)據(jù)庫(kù),緩存,消息代理。這篇文章主要介紹了Redis不僅僅是緩存,還是……,需要的朋友可以參考下
    2020-12-12
  • Redis設(shè)置Hash數(shù)據(jù)類(lèi)型的過(guò)期時(shí)間

    Redis設(shè)置Hash數(shù)據(jù)類(lèi)型的過(guò)期時(shí)間

    在Redis中,我們可以使用Hash數(shù)據(jù)結(jié)構(gòu)來(lái)存儲(chǔ)一組鍵值對(duì),而有時(shí)候,我們可能需要設(shè)置這些鍵值對(duì)的過(guò)期時(shí)間,本文主要介紹了Redis設(shè)置Hash數(shù)據(jù)類(lèi)型的過(guò)期時(shí)間,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • redis的三種啟動(dòng)實(shí)現(xiàn)方式(后臺(tái)運(yùn)行)

    redis的三種啟動(dòng)實(shí)現(xiàn)方式(后臺(tái)運(yùn)行)

    文章介紹了Redis的三種啟動(dòng)方式:直接運(yùn)行、通過(guò)配置文件啟動(dòng)及使用啟動(dòng)腳本設(shè)置開(kāi)機(jī)自啟,啟動(dòng)腳本需復(fù)制到/etc/init.d并重命名為redisd,同時(shí)添加運(yùn)行級(jí)別注釋以解決chkconfig報(bào)錯(cuò)問(wèn)題,確保服務(wù)可開(kāi)機(jī)自動(dòng)啟動(dòng)
    2025-07-07
  • Redis集群的關(guān)閉與重啟操作

    Redis集群的關(guān)閉與重啟操作

    這篇文章主要介紹了Redis集群的關(guān)閉與重啟操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • springboot中操作redis實(shí)例分享

    springboot中操作redis實(shí)例分享

    本文介紹了如何在Spring?Boot應(yīng)用中整合Redis緩存技術(shù),包括配置Redis連接、定義Redis模板、實(shí)現(xiàn)Redis的基本操作以及使用Spring?Cache注解。這些內(nèi)容可幫助開(kāi)發(fā)者快速掌握Spring?Boot與Redis的集成,并提高應(yīng)用性能。
    2023-06-06
  • odoo中使用redis實(shí)現(xiàn)緩存的步驟

    odoo中使用redis實(shí)現(xiàn)緩存的步驟

    這篇文章主要介紹了odoo中使用redis實(shí)現(xiàn)緩存的步驟,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-04-04

最新評(píng)論

宜丰县| 广东省| 波密县| 容城县| 周宁县| 呼玛县| 商南县| 堆龙德庆县| 汕尾市| 精河县| 共和县| 浦城县| 兴文县| 汤原县| 仪陇县| 土默特左旗| 霍州市| 沙坪坝区| 衡阳县| 镇江市| 洛隆县| 平南县| 乌拉特前旗| 阳高县| 新乐市| 河源市| 来宾市| 田东县| 麟游县| 壤塘县| 太谷县| 肃南| 皋兰县| 安塞县| 从江县| 丰宁| 虞城县| 呼伦贝尔市| 扶沟县| 虹口区| 张家川|