赞
踩
背景:线上 Redis
偶尔发生执行命令超时的异常:Command timed out after 1 minute(s)
,但是短时间又找不到具体原因,就想着把执行命令超时时间设置的短一点,查询 Redis
超时以后走 DB
,临时解决一下问题,然后再排查超时的具体原因,但是根据官方文档设置 spring.redis.timeout=2000
以后,并没有生效,也不知道原因,最后用 java
代码配置成功了,这里记录一下配置方法。
import io.lettuce.core.ClientOptions; import io.lettuce.core.SocketOptions; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; 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 org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.repository.configuration.EnableRedisRepositories; import org.springframework.data.redis.serializer.StringRedisSerializer; import java.time.Duration; /** * @author liuyuan * @version RedisConfig.java, v 0.1 2024-08-05 15:43 */ @Slf4j @Configuration @EnableRedisRepositories public class RedisConfig { @Value("${spring.redis.host}") private String redisHost; @Value("${spring.redis.port}") private int redisPort; @Value("${spring.redis.database}") private int redisDatabase; // 这里自定义了名称,是因为公司三方包里面已经有一个 RedisConnectionFactory 了,不换名称,不会加载 @Bean @Primary public RedisConnectionFactory customRedisConnectionFactory(LettuceClientConfiguration clientConfiguration) { log.info("RedisConfig.customRedisConnectionFactory() init........."); RedisStandaloneConfiguration standaloneConfiguration = new RedisStandaloneConfiguration(); standaloneConfiguration.setHostName(redisHost); standaloneConfiguration.setPort(redisPort); standaloneConfiguration.setDatabase(redisDatabase); return new LettuceConnectionFactory(standaloneConfiguration, clientConfiguration); } @Bean public LettuceClientConfiguration clientConfiguration() { log.info("RedisConfig.clientConfiguration() init........."); SocketOptions socketOptions = SocketOptions.builder() .connectTimeout(Duration.ofSeconds(1)) // 设置连接超时时间 .build(); ClientOptions clientOptions = ClientOptions.builder() .autoReconnect(true) // 是否自动重连 .pingBeforeActivateConnection(true) // 是否在激活连接前发送 PING 命令 .cancelCommandsOnReconnectFailure(false) // 是否在重连失败时取消命令 .disconnectedBehavior(ClientOptions.DisconnectedBehavior.ACCEPT_COMMANDS) // 设置断开连接时的行为 .socketOptions(socketOptions) .build(); return LettuceClientConfiguration.builder() .commandTimeout(Duration.ofSeconds(1)) // 设置命令执行超时时间 .clientOptions(clientOptions) .build(); } // 原本到上面为止,配置已经完成了,但是还是因为公司三方包里面已经有一个 RedisConnectionFactory 了,所以这里需要重新设置才会生效 // 如果只有一个 RedisConnectionFactory,下面的可以不要 @Bean @Primary public StringRedisTemplate stringRedisTemplate(@Qualifier("customRedisConnectionFactory") RedisConnectionFactory connectionFactory) { log.info("RedisConfig.stringRedisTemplate() init........."); return new StringRedisTemplate(connectionFactory); } @Bean(name = "redisTemplate") public RedisTemplate<String, String> redisTemplate(@Qualifier("customRedisConnectionFactory") RedisConnectionFactory connectionFactory) { log.info("RedisConfig.redisTemplate() init........."); RedisTemplate<String, String> template = new RedisTemplate<>(); template.setConnectionFactory(connectionFactory); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new StringRedisSerializer()); template.afterPropertiesSet(); return template; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。