Java SpringBoot2.3.4 配置redis 基于lettuce 同时支持集群与单机 配置密码加密 并使用redisson分布式锁

您所在的位置:网站首页 lettuce连接redis集群 Java SpringBoot2.3.4 配置redis 基于lettuce 同时支持集群与单机 配置密码加密 并使用redisson分布式锁

Java SpringBoot2.3.4 配置redis 基于lettuce 同时支持集群与单机 配置密码加密 并使用redisson分布式锁

2024-04-30 15:41| 来源: 网络整理| 查看: 265

项目的redisutil 使用的是jedis 升级项目新的springboot推荐使用lettuce

之前的写法过于臃肿 为单机和集群分别搞了一份代码 很多重复部分

只要基于配置文件 动态创建redisConnectionFactory就可以了

由于项目中各个数据库的密码在配置文件中都是加密的 所以有一段解密代码

代码语言:javascript复制package cn.mypro.config; import com.alibaba.druid.filter.config.ConfigTools; import lombok.extern.slf4j.Slf4j; import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.ClusterServersConfig; import org.redisson.config.Config; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.MapPropertySource; import org.springframework.data.redis.connection.RedisClusterConfiguration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisStandaloneConfiguration; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import java.util.HashMap; import java.util.Map; /** * 自定义redis connection factory 同时支持单机与集群配置 并支持redis密码的加密 * 若要增加更多配置项 则在lettuceConnectionFactory()中进行对应设置即可 * * @author wyh * @date 2020/9/25 11:29 **/ @Slf4j @Configuration @ConditionalOnClass(RedisTemplate.class) public class RedisConfig { @Value("${spring.redis.host}") private String host; @Value("${spring.redis.password}") private String password; @Value("${public-key}") private String publicKey; private static final String SEPARATOR = ","; private static final String HOST_PORT_SEPARATOR = ":"; @Bean public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate template = new RedisTemplate(); template.setConnectionFactory(redisConnectionFactory); template.setKeySerializer(new StringRedisSerializer()); template.setDefaultSerializer(RedisSerializer.json()); template.afterPropertiesSet(); return template; } @Bean public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) { StringRedisTemplate template = new StringRedisTemplate(); template.setConnectionFactory(redisConnectionFactory); return template; } @Bean public RedissonClient redissonClient() { Config config = new Config(); try { //解密redis密码 若配置文件使用的明文密码则不需要 String pwd = ConfigTools.decrypt(publicKey, password); if (host.split(SEPARATOR).length == 1) { config.useSingleServer().setAddress("redis://" + host).setPassword(pwd); return Redisson.create(config); } else { String[] split = host.split(SEPARATOR); ClusterServersConfig clusterServersConfig = new ClusterServersConfig(); for (String hostAndPort : split){ clusterServersConfig= config.useClusterServers().addNodeAddress("redis://" + hostAndPort); } if (!clusterServersConfig.getNodeAddresses().isEmpty()){ clusterServersConfig.setPassword(pwd); } return Redisson.create(config); } } catch (Exception e) { log.error("redis连接失败 请检查密码配置", e); } return null; } @Bean public LettuceConnectionFactory lettuceConnectionFactory() { try { //解密redis密码 若配置文件使用的明文密码则不需要 String pwd = ConfigTools.decrypt(publicKey, password); if (host.split(SEPARATOR).length == 1) { //单机模式 RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(); configuration.setHostName(host.split(HOST_PORT_SEPARATOR)[0]); configuration.setPort(Integer.parseInt(host.split(HOST_PORT_SEPARATOR)[1])); configuration.setPassword(pwd); return new LettuceConnectionFactory(configuration); } else { //集群模式 Map source = new HashMap(); source.put("spring.redis.cluster.nodes", host); source.put("spring.redis.cluster.password", pwd); RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration( new MapPropertySource("RedisClusterConfiguration", source)); return new LettuceConnectionFactory(redisClusterConfiguration); } } catch (Exception e) { log.error("redis连接失败 请检查密码配置", e); } return null; } }

这样配置文件中只需要配置spring.redis.host spring,redis.password

如果host带, 则代表为集群模式 否则为单机模式

redissonClient主要为了使用他的锁 锁可以自动续期 不必担心业务时间执行过长但锁释放的问题 之前试过的RedisLockRegistry依旧存在这个问题 所以选用redisson

附集成的更新后的redisUtil

接下来打算把原本硬编码的发布订阅也改成springboot模式

代码语言:javascript复制package cn.mypro.util; import org.redisson.api.RLock; import org.redisson.api.RReadWriteLock; import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.BoundListOperations; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; /** * @author wyh * @date 2020/9/25 11:47 **/ @Component public class RedisUtil { @Autowired private StringRedisTemplate redisTemplate; @Autowired private RedissonClient redissonClient; public RedisUtil(StringRedisTemplate redisTemplate) { this.redisTemplate = redisTemplate; } /** * 指定缓存失效时间 * @param key 键 * @param time 时间(秒) */ 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; } } /** * 根据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 String get(String key){ return key==null?null:redisTemplate.opsForValue().get(key); } /** * 普通缓存放入 * @param key 键 * @param value 值 * @return true成功 false失败 */ public boolean set(String key,String value) { try { redisTemplate.opsForValue().set(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 普通缓存放入并设置时间 * @param key 键 * @param value 值 * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 * @return true成功 false 失败 */ public boolean set(String key,String 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; } } /** * 递增 * @param key 键 * @param delta 要增加几(大于0) * @return */ public long incr(String key, long delta){ if(delta0){ expire(key, time); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 删除hash表中的值 * @param key 键 不能为null * @param item 项 可以使多个 不能为null */ public void hdel(String key, String... item){ redisTemplate.opsForHash().delete(key,item); } /** * 判断hash表中是否有该项的值 * @param key 键 不能为null * @param item 项 不能为null * @return true 存在 false不存在 */ public boolean hHasKey(String key, String item){ return redisTemplate.opsForHash().hasKey(key, item); } /** * hash递增 如果不存在,就会创建一个 并把新增后的值返回 * @param key 键 * @param item 项 * @param by 要增加几(大于0) * @return */ public double hincr(String key, String item,double by){ return redisTemplate.opsForHash().increment(key, item, by); } /** * hash递减 * @param key 键 * @param item 项 * @param by 要减少记(小于0) * @return */ public double hdecr(String key, String item,double by){ return redisTemplate.opsForHash().increment(key, item,-by); } //============================set============================= /** * 根据key获取Set中的所有值 * @param key 键 * @return */ public Set sGet(String key){ try { return redisTemplate.opsForSet().members(key); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 根据value从一个set中查询,是否存在 * @param key 键 * @param value 值 * @return true 存在 false不存在 */ public boolean sHasKey(String key,String value){ try { return redisTemplate.opsForSet().isMember(key, value); } catch (Exception e) { e.printStackTrace(); return false; } } /** * 将数据放入set缓存 * @param key 键 * @param values 值 可以是多个 * @return 成功个数 */ public long sSet(String key, String...values) { try { return redisTemplate.opsForSet().add(key, values); } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 将set数据放入缓存 * @param key 键 * @param time 时间(秒) * @param values 值 可以是多个 * @return 成功个数 */ public long sSetAndTime(String key,long time,String...values) { try { Long count = redisTemplate.opsForSet().add(key, values); if(time>0) { expire(key, time); } return count; } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 获取set缓存的长度 * @param key 键 * @return */ public long sGetSetSize(String key){ try { return redisTemplate.opsForSet().size(key); } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 移除值为value的 * @param key 键 * @param values 值 可以是多个 * @return 移除的个数 */ public long setRemove(String key, String ...values) { try { Long count = redisTemplate.opsForSet().remove(key, values); return count; } catch (Exception e) { e.printStackTrace(); return 0; } } //===============================list================================= /** * 获取list缓存的内容 * @param key 键 * @param start 开始 * @param end 结束 0 到 -1代表所有值 * @return */ public List lGet(String key, long start, long end){ try { return redisTemplate.opsForList().range(key, start, end); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 获取list缓存的长度 * @param key 键 * @return */ public long lGetListSize(String key){ try { return redisTemplate.opsForList().size(key); } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 通过索引 获取list中的值 * @param key 键 * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index 0) { expire(key, time); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 将list放入缓存 * @param key 键 * @param value 值 * @return */ public boolean lSet(String key, List value) { try { redisTemplate.opsForList().rightPushAll(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 将list放入缓存 * @param key 键 * @param value 值 * @param time 时间(秒) * @return */ public boolean lSet(String key, List value, long time) { try { redisTemplate.opsForList().rightPushAll(key, value); if (time > 0) { expire(key, time); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 根据索引修改list中的某条数据 * @param key 键 * @param index 索引 * @param value 值 * @return */ public boolean lUpdateIndex(String key, long index,String value) { try { redisTemplate.opsForList().set(key, index, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 移除N个值为value * @param key 键 * @param count 移除多少个 * @param value 值 * @return 移除的个数 */ public long lRemove(String key,long count,String value) { try { Long remove = redisTemplate.opsForList().remove(key, count, value); return remove; } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 模糊查询获取key值 * @param pattern * @return */ public Set keys(String pattern){ return redisTemplate.keys(pattern); } /** * 使用Redis的消息队列 * @param channel * @param message 消息内容 */ public void convertAndSend(String channel, String message){ redisTemplate.convertAndSend(channel,message); } /** * 根据起始结束序号遍历Redis中的list * @param listKey * @param start 起始序号 * @param end 结束序号 * @return */ public List rangeList(String listKey, long start, long end) { //绑定操作 BoundListOperations boundValueOperations = redisTemplate.boundListOps(listKey); //查询数据 return boundValueOperations.range(start, end); } /** * 弹出右边的值 --- 并且移除这个值 * @param listKey */ public String rifhtPop(String listKey){ //绑定操作 BoundListOperations boundValueOperations = redisTemplate.boundListOps(listKey); return boundValueOperations.rightPop(); } //===============================lock================================= public boolean tryLock(String key) { RLock lock = redissonClient.getLock(key); return lock.tryLock(); } public void unlock(String key){ RLock lock = redissonClient.getLock(key); lock.unlock(); } public RReadWriteLock rwLock(String key){ return redissonClient.getReadWriteLock(key); }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3