国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 數(shù)據(jù)庫(kù) > Redis > 正文

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

2020-10-28 21:29:12
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

1. 前言

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

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

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

redis.host1: 10.113.56.68redis.port1: 7030redis.host2: 10.113.56.68redis.port2: 7031redis.host3: 10.113.56.68redis.port3: 7032redis.host4: 10.113.56.68redis.port4: 7033redis.host5: 10.113.56.68redis.port5: 7034redis.host6: 10.113.56.68redis.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)聽redis中Key過期事件 **/@Configurationpublic 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過期監(jiān)聽,建立多個(gè)連接,對(duì)每個(gè)redis節(jié)點(diǎn)進(jìn)行監(jiān)聽  @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過期監(jiān)聽 **/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防止過期key重復(fù)監(jiān)聽

對(duì)于項(xiàng)目集群情況下,部署多個(gè)服務(wù)后,容易出現(xiàn)redis過期被多個(gè)服務(wù)同時(shí)監(jiān)聽到,從而執(zhí)行相同的業(yè)務(wù)邏輯,這不是我們期望的。單機(jī)部署下方法的同步可以采用synchronize關(guān)鍵字。但集群下,就得采用分布式鎖。在需要加鎖的地方,只要加鎖和解鎖即可。此處正好寫到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分布式鎖 **/@Componentpublic 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,廢話比較少。小白自己寫的配置類,理解有問題請(qǐng)留言!自己實(shí)現(xiàn)的方案感覺不妥,只是基本完成需求,還得繼續(xù)研究。

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

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 新津县| 万安县| 莱阳市| 永平县| 本溪| 迁西县| 云和县| 诸城市| 吉安县| 靖宇县| 海兴县| 中山市| 崇明县| 台湾省| 防城港市| 海阳市| 宣恩县| 高雄县| 夹江县| 花莲县| 元谋县| 琼中| 吕梁市| 霸州市| 兴文县| 喀喇| 韶关市| 呼伦贝尔市| 桦甸市| 江华| 荆州市| 乌拉特中旗| 吴旗县| 阳谷县| 阿拉善左旗| 平邑县| 曲靖市| 墨竹工卡县| 古交市| 灵石县| 扎赉特旗|