spring.cloud.config.fail-fast=true
您可以通过关闭Redis
服务器来使用我为我的问题创建的这个项目来重现。
下面是我的代码的样子-
@Lazy
@Configuration
public class RedisConfiguration {
@Value("${spring.redis.sentinel.master}")
private String SENTINEL_MASTER;
@Value("${spring.redis.sentinel.nodes}")
private String SENTINEL_NODES;
@Value("${spring.redis.security.enabled:false}")
private boolean REDIS_SECURITY_ENABLED;
@Value("${spring.redis.security.password:}")
private String REDIS_PASSWORD;
@Lazy
@Bean // somehow this always gets initialized
public RedisConnectionFactory jedisConnectionFactory() {
// create set of sentinel nodes
System.out.println(SENTINEL_NODES);
Set<String> sentinelNodesSet = new HashSet<>(5);
StringTokenizer st = new StringTokenizer(SENTINEL_NODES, ",");
while (st.hasMoreTokens())
sentinelNodesSet.add(st.nextToken());
RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration(SENTINEL_MASTER, sentinelNodesSet);
if (REDIS_SECURITY_ENABLED) {
sentinelConfig.setPassword(REDIS_PASSWORD);
}
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(sentinelConfig);
return jedisConnectionFactory;
}
下面是异常跟踪-
简而言之:
@lazy
注释适用于RedisstandalOneConfiguration
而不适用RedissentinelConfiguration
,不确定原因吗?@lazy
注释是有风险的,因为您需要确保使用redis
的所有服务都是懒散加载的。spring.cloud.config.fail-fast=true
的解决方案。更新:
在hood下,Spring Cloud Config使用spring-retry
和AOP(spring-boot-starter-aop
)配置重试机制。
此过程在ConfigServiceBootstrapConfiguration中实现。
守则的有关部分如下:
/* @ConditionalOnProperty("spring.cloud.config.fail-fast") */
@ConditionalOnClass({ Retryable.class, Aspect.class, AopAutoConfiguration.class })
@Configuration(proxyBeanMethods = false)
@EnableRetry(proxyTargetClass = true)
@Import(AopAutoConfiguration.class)
@EnableConfigurationProperties(RetryProperties.class)
protected static class RetryConfiguration {
@Bean
@ConditionalOnMissingBean(name = "configServerRetryInterceptor")
public RetryOperationsInterceptor configServerRetryInterceptor(
RetryProperties properties) {
return RetryInterceptorBuilder.stateless()
.backOffOptions(properties.getInitialInterval(),
properties.getMultiplier(), properties.getMaxInterval())
.maxAttempts(properties.getMaxAttempts()).build();
}
}
正如您所看到的,基本思想是提供一个RetryConfiguration
,它在认为应用程序失败之前处理一定数量的重试。
Spring Cloud Client的文档提供了更多关于用于配置该机制的不同属性的信息。您还可以在RetryProperties
类的源代码中看到默认值。
请尝试将两个必需的依赖项spring-retry
和spring-boot-starter-aop
以及retryconfiguration
作为主配置的子项,为重试机制的配置属性提供一些合理的默认值,然后看看会发生什么。
您可以将解决方案推向极限,并尝试在非常多的场合重新连接,也许增加它们之间的抑扬顿挫,等待服务器可用。
我认为@lazy
注释不再是必需的,可以安全地删除。
编辑
查看错误堆栈跟踪,您还可以尝试禁用字符串引导Redis自动配置类。
@SpringBootApplication(
exclude = { RedisAutoConfiguration.class, RedisRepositoriesAutoConfiguration.class }
)
spring.autoconfigure.exclude= \
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration, \
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration
您还可以使用此属性禁用Redis存储库配置:
spring.data.redis.repositories.enabled: false
一旦您禁用了Redis自动配置,您将可以自由地实例化redistemplate
或您认为合适时与Redis交互所需的东西。
例如,当实际需要时,您可以按需初始化它,尝试通过初始化所有所需的工厂来建立到Redis的连接。您可以使用try
和catch
包围初始化Redis连接所需的逻辑,并且只有在连接可用时才初始化Redistemplate
(如下所示)。
public RedisConnectionFactory jedisConnectionFactory() {
try {
// create set of sentinel nodes
System.out.println(SENTINEL_NODES);
Set<String> sentinelNodesSet = new HashSet<>(5);
StringTokenizer st = new StringTokenizer(SENTINEL_NODES, ",");
while (st.hasMoreTokens())
sentinelNodesSet.add(st.nextToken());
RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration(SENTINEL_MASTER, sentinelNodesSet);
if (REDIS_SECURITY_ENABLED) {
sentinelConfig.setPassword(REDIS_PASSWORD);
}
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(sentinelConfig);
return jedisConnectionFactory;
} catch (redis.clients.jedis.exceptions.JedisConnectionException re) {
logger.error("Unable to initialize Redis connection factory", re);
return null;
}
}
另一方面:
public RedisTemplate getRedisTemplate() {
// We can assume that both methods are defined in the same class,
// although it is not necessary
final RedisConnectionFactory redisConnectionFactory = this.jedisConnectionFactory();
if (redisConnectionFactory == null) {
return null;
}
final RedisTemplate redisTemplate = new StringRedisTemplate(redisConnectionFactory);
return redisTemplate;
}
您可以以您认为合适的方式使用这个redistemplate
,当然,还可以根据需要缓存和重用它。
这些方法可以在为此任务创建的服务或帮助器类中定义,当然,不能在您的配置类中定义。
问题内容: 我的一台Redis服务器今天反复停机,没有任何明显的可诊断原因。我所有的用户最终都会遇到错误。 查看处的日志,最后几行捕获的内容比计划的备份更为有害: pid文件仍然存在。这意味着服务器没有被正式关闭,redis仍被守护? 我登录到系统,并做了两次以使其启动并运行。除了这些日志,我还能如何诊断可能出了什么问题? 更新:我注意到在第一次崩溃时,磁盘交换开始发生。这从未发生过。此外,确认将
问题内容: 在我的 主服务器上 ,我从可通过api访问的外部/单独的 redis服务器中 获取数据 。但是,api是不安全的。而且由于我希望将 Redis服务器 分开,因此该技术不适合我的情况。 在我来说,我想有2台独立的服务器, 一个 和 乙 。 A 应该在不使用api或url调用的情况下从 B 加载数据…而是应使用 port (例如)。这样,服务器 乙 只能从访问的 一个 。 我希望这种方法适
问题内容: 我认为我非常接近让Java服务器应用程序通过WebRTC与浏览器页面对话,但是我不能完全使其正常工作。我感觉自己缺少一些小东西,因此希望这里有人可以提出建议。 我仔细研究了WebRTC示例- Java单元测试()和示例Android应用()。根据所学知识,我编写了一个Java应用程序,该应用程序使用WebSockets进行信号传输并尝试将视频流发送到Chrome。 问题是,即使我所有的
我想连接到树莓Pi节点。我从网络外部设置的js服务器。 我的路由器声称端口是开放的。我尝试在127.0.0.0、0.0.0.0和我的公共IP地址运行服务器。 我曾尝试使用ngrok打开端口8080,服务器在其中托管一个简单的网页,但尝试访问myIP:8080不起作用。 有人能帮我吗?
问题内容: 我显然正在运行一个实例,因为当我尝试通过输入来启动新服务器时,遇到了以下问题: 我不知道如何停止此服务器并启动新服务器。 在CLI中键入命令时,可以追加任何命令吗? 我的操作系统是Ubuntu 10.04。 问题答案: 连接到节点实例并使用shutdown命令,或者如果您在ubuntu上,则可以尝试通过init.d重新启动Redis服务器: 或停止/启动它: 在Mac上
我有3个复制的Redis实例运行在3台不同的机器上:A、B和C。我最初选择A作为我的主机。我还有3个哨兵(每台机器上有1个)监视A。