本文主要是介绍Springboot整合Redis主从实践,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
《Springboot整合Redis主从实践》:本文主要介绍Springboot整合Redis主从的实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教...
前言
SpringBoot版本:2.3.2.RELEASE
原配置
原yml配置内容:
spring: # Redis服务器配置 redis: host: 127.0.0.1 # Redis服务器连接端口 fLDsJoaSkC port: 6379 # Redis服务器连接密码 password: redis@123 #连接超时时间(毫秒) timeout: 30000ms jedis: # Redis服务器连接池 pool: # 连接池最大连接数(使用负值表示没有限制) maxIdle: 400 #连接池中的最小空闲连接 minIdle: 100 #连接池中的最大空闲连接 maxActive: 400 # 连接池最大阻塞等待时间(使用负值表示没有限制) maxWait: -1ms lettuce: pool: max-idle: 400 min-idle: 100 max-active: 400 max-wait: -1ms
原RedisConfig配置类:
import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; 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.StringRedisSerializer; @Configuration @EnableCaching @AutoConfigureAfter(RedisAutoConfiguration.class) public class RedisConfig { @Bean @ConditionalOnMissingBean(value = StringRedisTemplate.class, name = "stringRedisTemplate") public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) { StringRedisTemplate template = new StringRedisTemplate(); template.setConnectionFactory(factory); return template; } }
现配置
现yml配置内容:
spring: redis: # 主节点 master: host: 127.0.0.1 port: 6379 password: redis@123 # 副本节点 replicas: - host: 127.0.0.1 port: 6380 #连接超时时间(毫秒) timeout: 30000ms jedis: # Redis服务器连接池 pool: # 连接js池最大连接数(使用负值表示没有限制) maxIdle: 400 #连接池中的最小空闲连接 minIdle: 100 #连接池中的最大空闲连接 maxActive: 400 # 连接池最大阻塞等待时间(使用负值表示没有限制) maxWait: -1ms lettuce: pool: max-idle: 400 min-idle: 100 max-active: 400 max-wait: -1ms
现RedisConfig配置类:
import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer; import com.juxiao.xchat.manager.cache.properties.RedisMasterReplicaProperties; import io.lettuce.core.ClientOptions; import io.lettuce.core.ReadFrom; import org.apache.commons.lang3.StringUtils; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.Chttp://www.chinasem.cnonditionalOnMissingBean; import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; import org.springframework.boot.autoconfigure.data.redis.RedisProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; import org.springframework.co编程ntext.annotation.Configuration; import org.springframework.data.redis.connection.RedisPassword; import org.springframework.data.redis.connection.RedisStaticMasterReplicaConfiguration; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.serializer.StringRedisSerializer; @Configuration @EnableCaching @AutoConfigureAfter(RedisAutoConfiguration.class) @EnableConfigurationProperties({RedisMasterReplicaProperties.class, RedisProperties.class}) public class RedisConfig { private final RedisMasterReplicaProperties properties; private final RedisProperties redisProperties; public RedisConfig(RedisMasterReplicaProperties redisMasterReplicaProperties, RedisProperties redisProperties) { this.properties = redisMasterReplicaProperties; this.redisProperties = redisProperties; } public LettuceConnectionFactory redisConnectionFactory(boolean readFromMaster) { RedisStaticMasterReplicaConfiguration config = new RedisStaticMasterReplicaConfiguration( properties.getMaster().getHost(), properties.getMaster().getPort() ); String password = properties.getMaster().getPassword(); if (StringUtils.isNotBlank(password)) { config.setPassword(RedisPassword.of(password)); } for (RedisMasterReplicaProperties.Node replica : properties.getReplicas()) { config.addNode(replica.getHost(), replica.getPort()); } // 连接池配置 LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder builder = LettucePoolingClientConfiguration.builder().commandTimeout(redisProperties.getTimeout()); // 使用 application.yml 中的 lettuce.pool 参数 RedisProperties.Pool poolProps = redisProperties.getLettuce().getPool(); if (poolProps != null) { builder.poolConfig(poolConfig(poolProps)); } // 优先从副本读取 builder.readFrom(readFromMaster ? ReadFrom.MASTER : ReadFrom.REPLICA_PREFERRED); // 断开连接时拒绝命令[而不是再等待连接超时时间后再报错]、启用自动重连 builder.clientOptions(ClientOptions.builder() .disconnectedBehavior(ClientOptions.DisconnectedBehavior.REJECT_COMMANDS) .autoReconnect(true) .build()); LettucePoolingClientConfiguration lettucePoolingClientConfiguration = builder.build(); // 构建连接工厂 LettuceConnectionFactory factory = new LettuceConnectionFactory(config, lettucePoolingClientConfiguration); // 禁用共享连接 默认是true // factory.setShareNativeConnection(false); // 初始化工厂 否则调用StringRedisTemplate时会空指针 【因为redisConnectionFactory 方法没有使用@Bean注解将LettuceConnectionFactory交给Spring工厂管理 所以需要手动调用afterPropertiesSet方法初始化连接工厂】 factory.afterPropertiesSet(); return factory; } // 连接池参数绑定 private GenericObjectPoolConfig<?> poolConfig(RedisProperties.Pool poolProps) { GenericObjectPoolConfig<?> config = new GenericObjectPoolConfig<>(); config.setMaxTotal(poolProps.getMaxActive()); config.setMaxIdle(poolProps.getMaxIdle()); config.setMinIdle(poolProps.getMinIdle()); config.setMaxWaitMillis(poolProps.getMaxWait().toMillis()); return config; } @Bean @ConditionalOnMissingBean(name = "redisTemplate") public RedisTemplate<Object, Object> redisTemplate(LettuceConnectionFactory redisConnectionFactory) { redisConnectionFactory.setShareNativeConnection(false); RedisTemplate<Object, Object> template = new RedisTemplate<>(); //使用fastjson序列化 FastJsonRedisSerializer<Object> serializer = new FastJsonRedisSerializer<>(Object.class); // value值的序列化采用fastJsonRedisSerializer template.setValueSerializer(serializer); template.setHashValueSerializer(serializer); // key的序列化采用StringRedisSerializer template.setKeySerializer(new StringRedisSerializer()); template.setHashKeySerializer(new StringRedisSerializepythonr()); template.setConnectionFactory(redisConnectionFactory); return template; } @Bean("masterStringRedisTemplate") @ConditionalOnMissingBean(name = "masterStringRedisTemplate") public StringRedisTemplate masterStringRedisTemplate() { StringRedisTemplate template = new StringRedisTemplate(); template.setConnectionFactory(redisConnectionFactory(true)); return template; } @Bean("replicaStringRedisTemplate") @ConditionalOnMissingBean(name = "replicaStringRedisTemplate") public StringRedisTemplate replicaStringRedisTemplate() { StringRedisTemplate template = new StringRedisTemplate(); template.setConnectionFactory(redisConnectionFactory(false)); return template; } }
新增RedisMasterReplicaProperties配置类:
import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import Java.util.ArrayList; import java.util.List; @Data @ConfigurationProperties(prefix = "spring.redis") public class RedisMasterReplicaProperties { /** * 主节点 */ private Node master; /** * 从节点 */ private List<Node> replicas = new ArrayList<>(); @Data public static class Node { /** * 主机地址 */ private String host; /** * 端口 */ private int port; /** * 密码(主从模式master、slave密码必须设置一样的) */ private String password; } }
测试
@Resource(name = "masterStringRedisTemplate") private StringRedisTemplate masterStringRedisTemplate; @Resource(name = "replicaStringRedisTemplate") private StringRedisTemplate replicaStringRedisTemplate; @GetMapping("/test") public String test() { masterStringRedisTemplate.opsForValue().set("imu:test", "Hello6"); String value = replicaStringRedisTemplate.opsForValue().get("imu:test"); return value; }
LettuceConnectionFactory.setShareNativeConnection 方法的作用
代码中这一行被注释,保持了原本的默认配置true
// 禁用共享连接 默认是true // factory.setShareNativeConnection(false);
在 Spring Data Redis 中,LettuceConnectionFactory 是一个用于管理 Redis 连接的工厂类,而 setShareNativeConnection(boolean shareNativeConnection) 方法用于控制是否 共享底层的 Redis 连接。
true(默认):
- 适用于 大多数应用,多个 Redis 操作共享同一个底层连接,减少资源占用。
- 适用于 Spring Boot + RedisTemplate 场景。
false:
- 适用于 高并发、多线程环境,避免多个线程争抢同一个 Redis 连接。
- 适用于 WebFlux、Reactive、Pipeline 等场景。
一般来说,除非你的 Redis 操作出现 多线程连接争用问题,否则 不用手动修改 setShareNativeConnection,保持默认值即可!
而:
- shareNativeConnection = true
- (默认)时,Spring 只会创建 一个共享的 StatefulRedisConnection,那么 连接池的 max-active、max-idle、min-idle 这些配置不会生效。
- shareNativeConnection = false 时,每次请求都会新建连接,这时连接池才会管理多个连接,此时 max-active 等参数才会起作用。
- 也就是说我们在yml配置文件中配置的连接池信息都将不起作用
jedis: # Redis服务器连接池 pool: # 连接池最大连接数(使用负值表示没有限制) maxIdle: 400 #连接池中的最小空闲连接 minIdle: 100 #连接池中的最大空闲连接 maxActive: 400 # 连接池最大阻塞等待时间(使用负值表示没有限制) maxWait: -1ms lettuce: pool: max-idle: 400 min-idle: 100 max-active: 400 max-wait: -1ms
总结
这篇关于Springboot整合Redis主从实践的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!