在尝试从 SpringBoot 应用程序连接到 AWS 中托管的远程 Redis 实例时,
RedisConnectionFactory
一直尝试连接到 localhost:6379
,即使目标主机已以不同方式指定。我的开发笔记本电脑和我们的开发环境都会出现此问题。我能够从 Redis InSight 以及另一个微服务连接到目标主机,奇怪的是,该微服务与失败的微服务具有相同的配置。
这是我默认的配置类:
@Configuration
public class RedisCacheConfig {
@Value("${spring.data.redis.host}")
private String host;
@Value("${spring.data.redis.port}")
private String port;
@Value("${spring.caching.ttl.findAllBillingByEstadoTTL}")
private Integer findAllBillingByEstadoTTLValue;
@Bean
public ReactiveRedisConnectionFactory reactiveRedisConnectionFactory() {
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
config.setHostName(host);
config.setPort(Integer.parseInt(port));
LettuceClientConfiguration lettuceClientConfiguration = LettuceClientConfiguration.builder()
.useSsl()
.and()
.commandTimeout(Duration.ofMillis(6000))
.build();
return new LettuceConnectionFactory(config, lettuceClientConfiguration);
}
@Bean
GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer() {
return new GenericJackson2JsonRedisSerializer();
}
@Bean
public RedisCacheConfiguration redisCacheConfiguration() {
return RedisCacheConfiguration.defaultCacheConfig()
.disableCachingNullValues()
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(genericJackson2JsonRedisSerializer()));
}
@Bean
RedisCacheManagerBuilderCustomizer redisCacheManagerBuilderCustomizer() {
return (builder) -> builder
.withCacheConfiguration("findAllBillingByEstado",
RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(findAllBillingByEstadoTTLValue)));
}
}
如您所见,我没有为
LettuceConnectionFactory
使用无参数构造函数,这是 几个类似问题(例如这个问题)中显示的问题。之前没用过.useSsl()
的方法,但是基于这个问题试了一下,没有用。最后,基于这个GitHub问题为了依赖Spring的自动配置,我也去掉了ReactiveRedisConnectionFactory
bean,但它仍然坚持连接localhost
。
还有什么可能导致这个问题?
您没有提供足够的信息来充分确定这种情况下问题的根本原因,例如您使用的 Spring 位的版本?
你提到了 Spring“自动配置”,所以我假设你实际上是在使用 Spring Boot。
在你的标题中,你提到你正在使用
application.yml
文件配置你的 Spring [Boot] 应用程序,但你没有共享配置。
注意:使用
也建议使用 Spring Boot。application.yaml
注意:YAML 配置文件扩展名实际上是
,而不是.yaml
..yml
您的问题可能是您的
application.yaml
文件格式错误(必须准确;请参阅 docs):
spring:
data:
redis:
host: "some-host"
port: 6379
database: 0
username: "user"
password: "secret"
或者,也许您没有在 YAML 中正确声明必要的 Spring Boot、Redis 特定的应用程序属性?
您是否可能将 Spring 配置文件用于不同环境以及按环境附加配置文件?
我还认为您应该检查应用程序 YAML 配置文件的扩展名,因为(如果)您正在使用
.yml
,Spring Boot docs 明确指出 .yaml
。具体来说,查看此doc.
查看 Spring Boot for Redis(尤其是 Spring Data Redis)中的available properties,
spring.data.redis.host
和 spring.data.redis.port
都是有效的属性。
您实际上可以使用以下方式简化端口属性的注入:
@Value("${spring.data.redis.port}")
private int port;
Spring 将在此处处理值转换(从
String
到原始 int
,或者包装器 Integer
对象,它可以处理 null
赋值)。
虽然,您对这些 Redis 属性使用属性注入应该是不必要的......
我真的很好奇为什么你会首先声明一个
[Reactive]RedisConnectionFactory
豆?
当 Spring Data Redis 和 Redis(客户端)驱动程序都在您的应用程序类路径中时,Spring Boot 自动配置将自动配置 Redis 连接,例如通过声明
spring-boot-starter-data-redis
dependency.
注意:默认情况下,Spring Boot
dependency 在您的应用程序类路径上声明 Lettuce 驱动程序。见这里。另请参阅文档。spring-boot-starter-data-redis
注意:另请注意,如果您的应用程序需要“响应式”,那么您可能应该改为声明
dependency。spring-boot-starter-data-redis-reactive
查看 Spring Boot,
RedisAutoConfiguration
类从here 到here.
通过在您的应用程序配置中显式声明一个
RedisConnectionFactory
bean,您已经有效地“覆盖”了 Spring Boot 的自动配置。
如果您需要像这样自定义配置,那么您可以简单地在属性(使用 Java 属性或 YAML 配置)中进行,或者使用适当的
Customizer
.
所以,您的 Spring
@Configuration
课程可能只是:
@Configuration
class RedisCacheConfig {
@Bean
LettuceClientConfigurationBuilderCustomizer lettuceClientConfigurationBuilderCustomizer() {
return builder -> builder
.useSsl()
.and()
.commandTimeout(Duration.ofMillis(6000));
}
// your other (cache) bean configuration here
}
这应该在 Spring Boot 自动配置中触发此代码(line),特别是如果您尚未声明 Sentinel 或集群配置(如here所示),从而默认为“独立”。
当然,您始终可以通过注入属性来检查(调试或记录)您的 Spring Boot (Redis) 应用程序的配置,或者(推荐)注入
RedisProperties
(这里)或一个RedisConnectionDetails
对象(here),具体来说,它是由Spring Boot声明和自动配置的。您可以看到 Spring Boot 将这些对象注入到 Spring Boot RedisConnectionConfiguration
类here 的构造函数中。然后,您可以从其中一个对象以面向对象的方式访问 Redis 属性配置。
另外,要特别注意Spring Boot提供的“单机”配置(这里)