Pom 配置
<!-- 引入spring-data-redis组件,默认已集成Lettuce依赖SDK --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId><version>6.3.0.RELEASE</version></dependency><dependency><groupId>io.netty</groupId><artifactId>netty-transport-native-epoll</artifactId><version>4.1.100.Final</version><classifier>linux-x86_64</classifier></dependency>
配置代码
说明:
配置 Lettuce 连接池的 LIFO = false(即采用 FIFO 队列模式),否则在云环境 VIP 场景下会因连接响应时间差异导致负载不均,连接池失效的问题。
1. 默认的 LIFO(后进先出)模式会优先复用最新归还的连接,使部分响应快的连接成为“热连接”,而响应慢的连接长期闲置,导致后端实际负载倾斜。
2. 连接池失效:当某条连接因响应慢被暂时弃用,LIFO 机制会加剧新请求集中分配给少数活跃连接,放大单点瓶颈风险。
import java.time.Duration;import org.springframework.beans.factory.annotation.Value;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.RedisStandaloneConfiguration;import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;import io.lettuce.core.ClientOptions;import io.lettuce.core.SocketOptions;import org.apache.commons.pool2.impl.GenericObjectPoolConfig;import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;@Configurationpublic class lettuceSingleConfig {// @Value("${tencent.redis.host}")// private String redisHost;//// @Value("${tencent.redis.port:6379}")// private Integer redisPort = 6379;//// @Value("${tencent.redis.database:0}")// private Integer redisDatabase = 0;//// @Value("${tencent.redis.password:}")// private String redisPassword;@Value("${tencent.redis.connect.timeout:2000}")private Integer redisConnectTimeout = 2000;@Value("${tencent.redis.command.timeout:2000}")private Integer redisCommandTimeout = 2000;/*** TCP_KEEPALIVE 配置参数*/@Value("${tencent.redis.tcp.keepalive.time.idle:30}")private Integer redisTcpKeepaliveTimeIdle = 30;@Value("${tencent.redis.tcp.keepalive.time.interval:10}")private Integer redisTcpKeepaliveTimeInterval = 10;@Value("${tencent.redis.tcp.keepalive.count:3}")private Integer redisTcpKeepaliveCount = 3;/*** TCP_USER_TIMEOUT 解决Lettuce长时间超时问题*/@Value("${tencent.redis.tcp.user.timeout:30}")private Integer redisTcpUserTimeout = 30;/*** pool相关参数*/@Value("${tencent.redis.pool.max-wait:1000}")private Integer RedisPoolMaxwait = 1000;@Value("${tencent.redis.pool.max-active:2000}")private Integer RedisPoolMaxTotal = 2000;@Value("${tencent.redis.pool.max-idle:1000}")private Integer RedisPoolMaxIdle = 1000;@Value("${tencent.redis.pool.min-idle:500}")private Integer RedisPoolMinIdle = 500;/*** redisConnectionFactory以及相关参数(Host、Port、Database、Password)与 application.properties 配置方式二选一*/// @Bean// public LettuceConnectionFactory redisConnectionFactory(LettuceClientConfiguration clientConfiguration) {//// RedisStandaloneConfiguration standaloneConfiguration = new RedisStandaloneConfiguration();// standaloneConfiguration.setHostName(redisHost);// standaloneConfiguration.setPort(redisPort);// standaloneConfiguration.setDatabase(redisDatabase);// standaloneConfiguration.setPassword(redisPassword);//// LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(standaloneConfiguration, clientConfiguration);// connectionFactory.setDatabase(redisDatabase);// return connectionFactory;// }@Beanpublic LettuceClientConfiguration clientConfiguration() {SocketOptions socketOptions = SocketOptions.builder().keepAlive(SocketOptions.KeepAliveOptions.builder()// 连接空闲多久开始 keepalive.idle(Duration.ofSeconds(redisTcpKeepaliveTimeIdle))// 两次 keepalive 间的时间间隔.interval(Duration.ofSeconds(redisTcpKeepaliveTimeInterval))// keepalive 几次之后断开连接.count(redisTcpKeepaliveCount)// 是否开启保活连接.enable().build()).tcpUserTimeout(SocketOptions.TcpUserTimeoutOptions.builder()// 解决服务端rst导致的长时间超时问题.tcpUserTimeout(Duration.ofSeconds(redisTcpUserTimeout)).enable().build())// tcp 连接超时设置.connectTimeout(Duration.ofMillis(redisConnectTimeout)).build();ClientOptions clientOptions = ClientOptions.builder().autoReconnect(true).pingBeforeActivateConnection(true).cancelCommandsOnReconnectFailure(false).disconnectedBehavior(ClientOptions.DisconnectedBehavior.ACCEPT_COMMANDS).socketOptions(socketOptions).build();// 创建连接池配置并关闭LIFOGenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();poolConfig.setLifo(false); // 关闭LIFO,启用FIFO模式poolConfig.setMaxTotal(RedisPoolMaxTotal); // 可选:设置最大连接数poolConfig.setMaxIdle(RedisPoolMaxIdle); // 可选:设置最大空闲连接数poolConfig.setMinIdle(RedisPoolMinIdle); // 可选:设置最小空闲连接数poolConfig.setMaxWait(Duration.ofMillis(RedisPoolMaxwait));return LettucePoolingClientConfiguration.builder().poolConfig(poolConfig).commandTimeout(Duration.ofMillis(redisCommandTimeout)).clientOptions(clientOptions).build();}}