@Slf4j @Configuration public class RedisConfig11 extends CachingConfigurerSupport { @Value("${redis. maxIdle}") private int maxIdle; @Value("${redis. minIdle}") private int minIdle; @Value("${redis. maxTotal}") private int maxTotal; @Value("${redis. timeout}") private int timeout; @Value("${redis.cluster.nodes}") private String nodes; @Value("${redis.password}") private String password; @Autowired private CustomRedisKeySerializer customRedisKeySerializer; @Autowired private CustomRedisSerializer customRedisSerializer; @Bean(destroyMethod = "destroy") public LettuceConnectionFactory lettuceConnectionFactory() { // Connection pool configuration GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig(); // The maximum number of idle threads in the thread pool genericObjectPoolConfig.setMaxIdle(maxIdle); // The minimum number of idle threads in the thread pool genericObjectPoolConfig.setMinIdle(minIdle); // The maximum number of threads in the thread pool genericObjectPoolConfig.setMaxTotal(maxTotal); // When the connection pool is exhausted, the client should wait for the maximum time for a new connection, in milliseconds genericObjectPoolConfig.setMaxWaitMillis(timeout); genericObjectPoolConfig.setTestOnBorrow(false); ClusterClientOptions clusterClientOptions = ClusterClientOptions.builder() // close ping .pingBeforeActivateConnection(false) .build(); LettuceClientConfiguration lettuceClientConfiguration = LettucePoolingClientConfiguration.builder() .clientOptions(clusterClientOptions) // overtime time .shutdownTimeout(Duration.ofMillis(timeout)) .poolConfig(genericObjectPoolConfig) .build(); // redis cluster node ip:port English comma separated if (StringUtils. isEmpty(nodes)) { log.error("redis cluster node is empty"); throw new RuntimeException(); } String[] hostAndPorts = nodes. split(","); Set<RedisNode> nodes = new HashSet<>(); for (String hostAndPort : hostAndPorts) { String[] ipAndPort = hostAndPort. split(":"); nodes.add(new RedisNode(ipAndPort[0], Integer.parseInt(ipAndPort[1]))); } RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration(); redisClusterConfiguration.setClusterNodes(nodes); redisClusterConfiguration.setMaxRedirects(nodes.size()); redisClusterConfiguration.setPassword(RedisPassword.of(password)); // Create a connection according to the configuration and client configuration LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(redisClusterConfiguration, lettuceClientConfiguration); lettuceConnectionFactory. afterPropertiesSet(); return lettuceConnectionFactory; } @Bean public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) { // set serialization Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = jackson2JsonRedisSerializer(); // configure redisTemplate RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(lettuceConnectionFactory); // key serialization redisTemplate.setKeySerializer(customRedisSerializer); // value serialization redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); // Hash key serialization redisTemplate.setHashKeySerializer(customRedisSerializer); // Hash value serialization redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); redisTemplate.afterPropertiesSet(); return redisTemplate; } @Bean public CacheManager cacheManager(LettuceConnectionFactory lettuceConnectionFactory) { // Configure serialization (the cache is valid for 6 hours by default) RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(6)); RedisCacheConfiguration redisCacheConfiguration = config .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())) .computePrefixWith(customRedisKeySerializer); return RedisCacheManager // Create a RedisCacheWriter object by means of lock writing .builder(RedisCacheWriter.lockingRedisCacheWriter(lettuceConnectionFactory)) .cacheDefaults(redisCacheConfiguration) .transactionAware() .build(); } private Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer() { Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); jackson2JsonRedisSerializer.setObjectMapper(new ObjectMapper() .setVisibility(PropertyAccessor.ALL, Visibility.ANY).enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL)); return jackson2JsonRedisSerializer; } }
@Slf4j @Component public class CustomRedisSerializer implements RedisSerializer<String> { @Value("${system.id}") private String systemId; @Override public byte[] serialize(String s) throws SerializationException { String keyPrefix = systemId + ":"; String key = keyPrefix + s; return key.getBytes(StandardCharsets.UTF_8); } @Override public String deserialize(byte[] bytes) throws SerializationException { String keyPrefix = systemId + ":"; String key = new String(bytes, StandardCharsets. UTF_8); int indexOf = key. indexOf(keyPrefix); if (indexOf > 0) { log.info("key missing prefix"); } else { int index = indexOf + keyPrefix. length(); key = key.substring(index); } log.info("saveKey:{}", key); return key; } }
@Slf4j @Component public class CustomRedisKeySerializer implements CacheKeyPrefix { @Value("${system.id}") private String systemId; @Override public String compute(String cacheName) { // You need to customize the key generation rules, and add the system prefix before the key String keyPrefix = systemId + ":"; return keyPrefix + cacheName + "::"; } }
@Component public class RedisUtils { @Resource private RedisTemplate<String, Object> redisTemplate; /** * Specifies the cache expiration time * * @param key key * @param time time (seconds) */ public void expire(String key, long time) { try { if (time > 0) { redisTemplate.expire(key, time, TimeUnit.SECONDS); } } catch (Exception e) { e.printStackTrace(); } } /** * Get the expiration time according to the key * * @param key key cannot be null * @return time (seconds) return 0 means it is permanent */ public long getExpire(String key) { Long expire = redisTemplate.getExpire(key, TimeUnit.SECONDS); return ObjectUtils.isEmpty(expire) ? 0L : expire; } /** * Determine whether the key exists * * @param key key * @return true exists false does not exist */ public boolean hasKey(String key) { try { return Boolean.TRUE.equals(redisTemplate.hasKey(key)); } catch (Exception e) { e.printStackTrace(); return false; } } /** * delete cache * * @param key can pass one value or more */ @SuppressWarnings("unchecked") public void del(String... key) { if (key != null & amp; & amp; key. length > 0) { if (key. length == 1) { redisTemplate.delete(key[0]); } else { redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key)); } } } // =============================String==================== ========== /** * Ordinary cache acquisition * * @param key key * @return value */ public Object get(String key) { return key == null ? null : redisTemplate.opsForValue().get(key); } /** * Ordinary cache put * * @param key key * @param value value * @return true success false failure */ public boolean set(String key, Object value) { try { redisTemplate.opsForValue().set(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * Ordinary cache is put in and set time * * @param key key * @param value value * @param time time (seconds) time must be greater than 0, if time is less than or equal to 0, it will be set indefinitely * @return true success false failure */ 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; } } /** * increment * * @param key key * @param delta How much to increase (greater than 0) * @return incremented result */ public long incr(String key, long delta) { if (delta < 0) { throw new RuntimeException("Increment factor must be greater than 0"); } Long increment = redisTemplate.opsForValue().increment(key, delta); return ObjectUtils.isEmpty(increment) ? 0L : increment; } /** * decrement * * @param key key * @param delta how much to reduce (less than 0) * @return long decremented result */ public long decr(String key, long delta) { if (delta < 0) { throw new RuntimeException("The decrement factor must be greater than 0"); } Long increment = redisTemplate.opsForValue().increment(key, -delta); return ObjectUtils.isEmpty(increment) ? 0L : increment; } // =================================Map================ =================== /** * HashGet * * @param key key cannot be null * @param item item cannot be null * @return value */ public Object hget(String key, String item) { return redisTemplate.opsForHash().get(key, item); } /** * Get all key values corresponding to hashKey * * @param key key * @return corresponding multiple key values */ public Map<Object, Object> hmget(String key) { return redisTemplate.opsForHash().entries(key); } /** * HashSet * * @param key key * @param map corresponds to multiple key values * @return true success false failure */ public boolean hmset(String key, Map<String, Object> map) { try { redisTemplate.opsForHash().putAll(key, map); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * HashSet and set the time * * @param key key * @param map corresponds to multiple key values * @param time time (seconds) * @return true success false failure */ public boolean hmset(String key, Map<String, Object> map, long time) { try { redisTemplate.opsForHash().putAll(key, map); if (time > 0) { expire(key, time); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * Put data into a hash table, if it does not exist, it will be created * * @param key key * @param item item * @param value value * @return true success false failure */ public boolean hset(String key, String item, Object value) { try { redisTemplate.opsForHash().put(key, item, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * Put data into a hash table, if it does not exist, it will be created * * @param key key * @param item item * @param value value * @param time Time (seconds) Note: If the existing hash table has time, the original time will be replaced here * @return true success false failure */ public boolean hset(String key, String item, Object value, long time) { try { redisTemplate.opsForHash().put(key, item, value); if (time > 0) { expire(key, time); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * Delete the value in the hash table * * @param key key cannot be null * @param item item can be multiple and cannot be null */ public void hdel(String key, Object... item) { redisTemplate.opsForHash().delete(key, item); } /** * Determine whether there is a value for this item in the hash table * * @param key key cannot be null * @param item item cannot be null * @return true exists false does not exist */ public boolean hHasKey(String key, String item) { return redisTemplate.opsForHash().hasKey(key, item); } /** * hash increment If it does not exist, it will create one and return the newly added value * * @param key key * @param item item * @param by how much to increase (greater than 0) * @return hash incremented result */ public double hincr(String key, String item, double by) { return redisTemplate.opsForHash().increment(key, item, by); } /** * hash decrement * * @param key key * @param item item * @param by to reduce (less than 0) * @return hash decremented result */ public double hdecr(String key, String item, double by) { return redisTemplate.opsForHash().increment(key, item, -by); } // ================================================= ========== /** * Get all the values in the Set according to the key * * @param key key * @return Set<Object> */ public Set<Object> sGet(String key) { try { return redisTemplate.opsForSet().members(key); } catch (Exception e) { e.printStackTrace(); return null; } } /** * Query from a set according to value, whether it exists * * @param key key * @param value value * @return true exists false does not exist */ public boolean sHasKey(String key, Object value) { try { return Boolean.TRUE.equals(redisTemplate.opsForSet().isMember(key, value)); } catch (Exception e) { e.printStackTrace(); return false; } } /** * Put the data into the set cache * * @param key key * @param values value can be multiple * @return number of successes */ public long sSet(String key, Object... values) { try { Long add = redisTemplate.opsForSet().add(key, values); return ObjectUtils.isEmpty(add) ? 0L : add; } catch (Exception e) { e.printStackTrace(); return 0; } } /** * Put the set data into the cache * * @param key key * @param time time (seconds) * @param values value can be multiple * @return number of successes */ public long sSetAndTime(String key, long time, Object... values) { try { Long count = redisTemplate.opsForSet().add(key, values); if (time > 0) { expire(key, time); } return ObjectUtils.isEmpty(count) ? 0L : count; } catch (Exception e) { e.printStackTrace(); return 0; } } /** * Get the length of the set cache * * @param key key * @return Get the length of the set */ public long sGetSetSize(String key) { try { Long size = redisTemplate.opsForSet().size(key); return ObjectUtils.isEmpty(size) ? 0L : size; } catch (Exception e) { e.printStackTrace(); return 0; } } /** * Remove the value of value * * @param key key * @param values value can be multiple * @return the number of removed */ public long setRemove(String key, Object... values) { try { Long count = redisTemplate.opsForSet().remove(key, values); return ObjectUtils.isEmpty(count) ? 0L : count; } catch (Exception e) { e.printStackTrace(); return 0; } } // ================================= list================== ================== /** * Get the content of the list cache * * @param key key * @param start start * @param end end 0 to -1 represent all values * @return List<Object> */ public List<Object> lGet(String key, long start, long end) { try { return redisTemplate.opsForList().range(key, start, end); } catch (Exception e) { e.printStackTrace(); return null; } } /** * Get the length of the list cache * * @param key key */ public long lGetListSize(String key) { try { Long size = redisTemplate.opsForList().size(key); return ObjectUtils.isEmpty(size) ? 0L : size; } catch (Exception e) { e.printStackTrace(); return 0; } } /** * Get the value in the list by index * * @param key key * @param index index index>=0, 0 is the header, 1 is the second element, and so on; when index<0, -1 is the end of the table, -2 is the second-to-last element, and so on * @return Object */ public Object lGetIndex(String key, long index) { try { return redisTemplate.opsForList().index(key, index); } catch (Exception e) { e.printStackTrace(); return null; } } /** * Put the list into the cache * * @param key key * @param value value */ public boolean lSet(String key, Object value) { try { redisTemplate.opsForList().rightPush(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * Put the list into the cache and specify the expiration time * * @param key key * @param value value * @param time time (seconds) */ public boolean lSet(String key, Object value, long time) { try { redisTemplate.opsForList().rightPush(key, value); if (time > 0) { expire(key, time); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * Put the list into the cache in batches * * @param key key * @param value value */ public boolean lSet(String key, List<Object> value) { try { redisTemplate.opsForList().rightPushAll(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * Put the list into the cache * * @param key key * @param value value * @param time time (seconds) * @return Boolean */ public boolean lSet(String key, List<Object> value, long time) { try { redisTemplate.opsForList().rightPushAll(key, value); if (time > 0) { expire(key, time); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * Modify a piece of data in the list according to the index * * @param key key * @param index index * @param value value * @return operation result */ public boolean lUpdateIndex(String key, long index, Object value) { try { redisTemplate.opsForList().set(key, index, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * Remove N values as value * * @param key key * @param count how many to remove * @param value value * @return the number of removed */ public long lRemove(String key, long count, Object value) { try { Long remove = redisTemplate.opsForList().remove(key, count, value); return ObjectUtils.isEmpty(remove) ? 0L : remove; } catch (Exception e) { e.printStackTrace(); return 0; } } }