RedisTemplate自适应Redis配置模式config
RedisTemplate配置Java源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 | import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.interceptor.CacheErrorHandler; 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.*; import org.springframework.data.redis.connection.jedis.JedisClientConfiguration; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.util.StringUtils; import redis.clients.jedis.HostAndPort; import redis.clients.jedis.JedisPoolConfig; import java.util.LinkedHashSet; import java.util.Set; /** * 自适应Redis配置模式config */ @Slf4j @Configuration @EnableCaching public class RedisTemplateConfig extends CachingConfigurerSupport { @Value ( "${spring.redis.host:}" ) private String node; @Value ( "${spring.redis.timeout:0}" ) private int timeout; @Value ( "${spring.redis.password:}" ) private String password; @Value ( "${spring.redis.sentinel.nodes:}" ) private String sentinel; @Value ( "${spring.redis.sentinel.master:}" ) private String master; @Value ( "${spring.redis.database:0}" ) private Integer database; @Value ( "${spring.redis.jedis.pool.max-total:8}" ) private int maxTotal; @Value ( "${spring.redis.jedis.pool.max-idle:8}" ) private int maxIdle; @Value ( "${spring.redis.jedis.pool.min-idle:0}" ) private int minIdle; @Value ( "${spring.redis.jedis.pool.max-wait:-1}" ) private long maxWaitMillis; @Value ( "${spring.redis.jedis.pool.test-on-borrow:true}" ) private boolean testOnBorrow; @Value ( "${spring.redis.jedis.factory.max-redirects:5}" ) private int maxRedirect; @Autowired private JedisPoolConfig jedisPoolConfig; @Autowired private JedisConnectionFactory jedisConnectionFactory; @Bean @ConditionalOnMissingBean @Override public CacheManager cacheManager() { // 初始化缓存管理器,在这里我们可以缓存的整体过期时间什么的,我这里默认没有配置 log.info( "初始化 -> [{}]" , "CacheManager RedisCacheManager Start" ); RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager .RedisCacheManagerBuilder .fromConnectionFactory(jedisConnectionFactory); return builder.build(); } @Bean @ConditionalOnMissingBean @Override public CacheErrorHandler errorHandler() { // 异常处理,当Redis发生异常时,打印日志,但是程序正常走 log.info( "初始化 -> [{}]" , "Redis CacheErrorHandler" ); return new CacheErrorHandler() { @Override public void handleCacheGetError(RuntimeException e, Cache cache, Object key) { log.error( "Redis occur handleCacheGetError:key -> [{}]" , key, e); } @Override public void handleCachePutError(RuntimeException e, Cache cache, Object key, Object value) { log.error( "Redis occur handleCachePutError:key -> [{}];value -> [{}]" , key, value, e); } @Override public void handleCacheEvictError(RuntimeException e, Cache cache, Object key) { log.error( "Redis occur handleCacheEvictError:key -> [{}]" , key, e); } @Override public void handleCacheClearError(RuntimeException e, Cache cache) { log.error( "Redis occur handleCacheClearError:" , e); } }; } @Bean @ConditionalOnMissingBean public JedisPoolConfig jedisPoolConfig() { JedisPoolConfig config = new JedisPoolConfig(); // 获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间, 默认-1 config.setMaxWaitMillis(maxWaitMillis); //最小空闲连接数, 默认0 config.setMinIdle(minIdle); //最大空闲连接数, 默认8个 config.setMaxIdle(maxIdle); //最大连接数, 默认值8个 config.setMaxTotal(maxTotal); //对拿到的connection进行validateObject校验 config.setTestOnBorrow(testOnBorrow); return config; } @Bean @ConditionalOnMissingBean public JedisConnectionFactory jedisConnectionFactory() { JedisConnectionFactory factory = null ; Set<HostAndPort> nodes = new LinkedHashSet<>(); if (!StringUtils.isEmpty(node)) { String[] split = node.split( "," ); for (String s : split) { try { String[] split1 = s.split( ":" ); nodes.add( new HostAndPort(split1[ 0 ], Integer.parseInt(split1[ 1 ]))); } catch (Exception e) { throw new RuntimeException(String.format( "出现配置错误!请确认node=[%s]是否正确" , node)); } } } //获得默认的连接池构造器 JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jpcb = (JedisClientConfiguration.JedisPoolingClientConfigurationBuilder) JedisClientConfiguration.builder(); //指定jedisPoolConifig来修改默认的连接池构造器 jpcb.poolConfig(jedisPoolConfig); //通过构造器来构造jedis客户端配置 JedisClientConfiguration jedisClientConfiguration = jpcb.build(); //如果是哨兵的模式 if (!StringUtils.isEmpty(sentinel)) { log.info( "Redis use SentinelConfiguration" ); RedisSentinelConfiguration redisSentinelConfiguration = new RedisSentinelConfiguration(); String[] sentinelArray = sentinel.split( "," ); for (String s : sentinelArray) { try { String[] split1 = s.split( ":" ); redisSentinelConfiguration.addSentinel( new RedisNode(split1[ 0 ], Integer.parseInt(split1[ 1 ]))); } catch (Exception e) { throw new RuntimeException(String.format( "出现配置错误!请确认node=[%s]是否正确" , node)); } } redisSentinelConfiguration.setPassword(password); redisSentinelConfiguration.setMaster(master); redisSentinelConfiguration.setDatabase(database); factory = new JedisConnectionFactory(redisSentinelConfiguration, jedisClientConfiguration); } //如果是单个节点 用Standalone模式 else if (nodes.size() == 1 ) { log.info( "Redis use RedisStandaloneConfiguration" ); for (HostAndPort n : nodes) { RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(); if (!StringUtils.isEmpty(password)) { redisStandaloneConfiguration.setPassword(RedisPassword.of(password)); } redisStandaloneConfiguration.setPort(n.getPort()); redisStandaloneConfiguration.setHostName(n.getHost()); redisStandaloneConfiguration.setDatabase(database); factory = new JedisConnectionFactory(redisStandaloneConfiguration, jedisClientConfiguration); } } //集群配置信息实现 else { log.info( "Redis use RedisStandaloneConfiguration" ); RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration(); nodes.forEach(n -> { redisClusterConfiguration.addClusterNode( new RedisNode(n.getHost(), n.getPort())); }); if (!StringUtils.isEmpty(password)) { redisClusterConfiguration.setPassword(RedisPassword.of(password)); } redisClusterConfiguration.setMaxRedirects(maxRedirect); factory = new JedisConnectionFactory(redisClusterConfiguration, jedisClientConfiguration); } return factory; } @Bean @ConditionalOnMissingBean public RedisTemplate<String, Object> redisTemplate(JedisConnectionFactory jedisConnectionFactory) { //设置序列化 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object. class ); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); // 配置redisTemplate RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(jedisConnectionFactory); RedisSerializer<String> stringSerializer = new StringRedisSerializer(); // key序列化 redisTemplate.setKeySerializer(stringSerializer); // value序列化 redisTemplate.setValueSerializer( new GenericJackson2JsonRedisSerializer()); // Hash key序列化 redisTemplate.setHashKeySerializer(stringSerializer); // Hash value序列化 redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); redisTemplate.afterPropertiesSet(); return redisTemplate; } } |
application.properties配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | spring.redis.sentinel.master=mymaster spring.redis.sentinel.nodes= 10.108 . 3.86 : 26379 , 10.108 . 3.186 : 26379 , 10.108 . 3.187 : 26379 spring.redis.password=vm-ubunut-sentinel spring.redis.database= 0 spring.redis.timeout= 1000 spring.redis.client-type=jedis #最大连接数, 默认值 8 个 spring.redis.jedis.pool.max-total= 8 #最大空闲连接数, 默认 8 个 spring.redis.jedis.pool.max-idle= 8 #最小空闲连接数, 默认 0 spring.redis.jedis.pool.min-idle= 0 #获取连接时的最大等待毫秒数,如果超时就抛异常, 小于零:阻塞不确定的时间, 默认- 1 spring.redis.jedis.pool.max-wait=- 1 #对拿到的connection进行validateObject校验 spring.redis.jedis.pool.test-on-borrow= true #集群时最大重定向个数默认 5 spring.redis.jedis.factory.max-redirects= 5 |
以上spring.redis.sentinel.nodes是我配置的局域网redis哨兵,有兴趣可移步查看:https://www.cnblogs.com/huyueping/p/16851934.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构