【问题标题】:SpringBoot Redis remote hostSpringBoot Redis 远程主机
【发布时间】:2019-01-25 15:50:18
【问题描述】:

我正在制作一个在后端使用 Spring Boot、MySQL 和 Redis 并在前端使用 Angular 的应用程序。我想将它部署到 Heroku,这样我就可以使用我的前端,但我似乎无法为 Redis 配置远程 URL。为此,我在 Heroku 上安装了 Redis To Go 插件,并准备好了远程 URL。我只是不知道如何配置环境变量来访问它而不是 localhost 和默认端口 6379。

我在 application.properties 中添加了以下几行,但它仍然不起作用:

spring.redis.url= #URL
spring.redis.host= #HOSTNAME
spring.redis.password= #PASSWORD
spring.redis.port = #PORT

我不断收到以下错误:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'enableRedisKeyspaceNotificationsInitializer' defined in class path resource [org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfiguration.class]: Invocation of init method failed; nested exception is org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis on localhost:6379; nested exception is com.lambdaworks.redis.RedisConnectionException: Unable to connect to localhost/127.0.0.1:6379

有什么方法可以配置它来访问远程 url 而不是 localhost?

我使用的是生菜而不是 Jedis,我的 HttpSessionConfig 文件是:

@EnableRedisHttpSession
public class HttpSessionConfig {

    @Bean
    public LettuceConnectionFactory connectionFactory() {
        return new LettuceConnectionFactory();
    }

}

【问题讨论】:

  • 您实际上是使用“#HOSTNAME”作为 spring.redis.host 属性还是正确的主机名?如果没有,请将#HOSTNAME 替换为远程 url 中的主机名,然后重试。
  • 我使用了正确的主机名

标签: java spring-boot redis lettuce


【解决方案1】:

我遇到了类似的问题,我就是这样解决的:

如果你这样定义 bean:

@Bean
public LettuceConnectionFactory connectionFactory() {
    return new LettuceConnectionFactory();
}

您不允许 Spring 从 application.properties 获取 Redis 值。

要使其正常工作,请执行以下操作:

  1. 删除此 bean 定义:
@Bean
public LettuceConnectionFactory connectionFactory() {
    return new LettuceConnectionFactory();
}
  1. 以这种方式定义 RedisTemplate bean:
@Bean
public RedisTemplate<String, Object> deliveryRedisTemplate(RedisConnectionFactory connectionFactory) {
    RedisTemplate<String, Object> template = new RedisTemplate<>();
    template.setConnectionFactory(connectionFactory);
    return template;
}
  1. application.properties 中定义以下值:
spring.redis.database=<replace-me>
spring.redis.host=<replace-me>
spring.redis.port=<replace-me>
spring.redis.timeout=<replace-me>

【讨论】:

    【解决方案2】:

    我对您面临的完全相同的问题感到沮丧,并且 Spring Boot 文档或示例无法解决我们所面临的问题。未使用配置条目的原因是因为您正在使用无参数构造函数创建 LettuceConnectionFactory 的新实例。深入研究源代码/字节代码,您可以看到构造函数完全忽略了 spring.redis.host 和 spring.redis.port 值并将它们硬编码到 localhost:6379。

    你应该做的是:

    • 使用 LettuceConnectionFactory(hostname, port) 构造函数。
    • 不要定义连接工厂。去掉 connectionFactory() 的整个 @Bean 条目,Spring 将自动连接所有内容并使用您的配置条目。

    也作为旁注;为了让它与 AWS Elasticache 一起工作(通过 VPN 在本地),我必须添加到该配置类:

    @Bean
    public static ConfigureRedisAction configureRedisAction() {
        return ConfigureRedisAction.NO_OP;
    }
    

    【讨论】:

      【解决方案3】:

      我发现连接到他们的 Redis 插件 (https://devcenter.heroku.com/articles/heroku-redis#connecting-in-java) 的 Heroku 文档包含一个使用 Jedis 的示例,因此需要稍作修改。 Heroku 添加到您正在运行的应用程序环境中的REDIS_URL 的内容类似于

      redis://h:credentials@host:port
      

      我使用RedisURI.create解析这个然后设置RedisStandaloneConfiguration的主机、端口和密码参数

      val uri = RedisURI.create(configuration.redisUrl)
      val config = RedisStandaloneConfiguration(uri.host, uri.port)
      config.setPassword(uri.password)
      return LettuceConnectionFactory(config)
      

      上面的代码是 Kotlin 而不是 Java,但也许它会有所帮助?你可以在https://github.com/DangerousDarlow/springboot-redis找到完整的代码

      【讨论】:

        【解决方案4】:

        您需要根据自动配置或定义自定义连接模板进行选择。

        第一种方法是删除HttpSessionConfig,然后将应用application.properties 文件中的redis 属性。由于您对类路径具有 spring-redis-data-session 依赖项,因此您的生菜连接将被隐式创建。

        第二种解决方案是将您的连接属性定义为LettuceConnectionFactory 中的主机、端口、密码。

        但建议使用自动配置。

        【讨论】:

        • 好的,这两种方法我都试过了。当我删除 HttpSessonConfig 时,我收到错误 - org.springframework.context.ApplicationContextException:无法启动嵌入式容器;嵌套异常是 org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat
        • 当我尝试在 LettuceConnectionFactory 中定义连接时,它给了我同样的错误。
        • 您发布的错误消息太少,无法得出答案,这是不同的问题,因此您应该创建另一个问题。
        【解决方案5】:

        在 application.properties 和 RedisStandaloneConfiguration 中设置配置。

        @Configuration
        @PropertySource("application.properties")
        @EnableRedisHttpSession
        public class SpringRedisConfig {
        
                    @Autowired
                    private Environment env;
        
                    @Bean
                    public LettuceConnectionFactory connectionFactory() {
        
                        RedisStandaloneConfiguration redisConf = new RedisStandaloneConfiguration();
                        redisConf.setHostName(env.getProperty("spring.redis.host"));
                        redisConf.setPort(Integer.parseInt(env.getProperty("spring.redis.port")));
                        redisConf.setPassword(RedisPassword.of(env.getProperty("spring.redis.password")));
        
                        return new LettuceConnectionFactory(redisConf);
                    }
            }
        

        【讨论】:

          猜你喜欢
          • 2022-01-13
          • 2016-12-20
          • 1970-01-01
          • 1970-01-01
          • 2018-04-28
          • 2014-05-14
          • 1970-01-01
          • 2012-11-15
          • 2011-12-16
          相关资源
          最近更新 更多