SpringBoot Redis remote host
Asked Answered
P

5

8

I'm making an application that uses Spring Boot, MySQL and Redis on the Back End and Angular on the Front End. I want to deploy it to Heroku so I could use my front end with it but I just can't seem to configure the remote URL for Redis. I have the Redis To Go Add-on on Heroku for this with the remote URL ready. I just don't know how to configure the environment variables to access that instead of localhost and the default port 6379.

I added the following lines to my application.properties but it still did not work :

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

I keep getting the following error :

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

Is there any way I could configure this to access the remote url instead of localhost?

I'm using Lettuce and not Jedis and my HttpSessionConfig file is :

@EnableRedisHttpSession
public class HttpSessionConfig {

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

}
Pickar answered 19/8, 2018 at 6:28 Comment(2)
did you actually use '#HOSTNAME' for spring.redis.host property or a proper hostname? If not, replace #HOSTNAME with hostname from the remote url and try again.Eller
I used a proper hostnamePickar
A
9

I was frustrated with the exact same issue you are facing and the spring boot documentation or examples do nothing to address what we are facing. The reason why your config entries are not being used is because you are creating a new instance of LettuceConnectionFactory with a parameter-less constructor. Digging into the source/byte code you can see that constructor is completely ignoring the spring.redis.host and spring.redis.port values and hardcoding them to localhost:6379.

What you should be doing is either:

  • Use the LettuceConnectionFactory(hostname, port) constructor.
  • Don't define the connection factory. Get rid of the entire @Bean entry for connectionFactory() and Spring will automatically wire everything up and use your config entries.

Also as a side note; to get this working with AWS Elasticache (locally via VPN) I had to add to that config class:

@Bean
public static ConfigureRedisAction configureRedisAction() {
    return ConfigureRedisAction.NO_OP;
}
Ansley answered 17/9, 2018 at 6:51 Comment(0)
P
9

I was having a similar issue, this is how I solved it:

If you define the bean this way:

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

You are not allowing Spring to take the Redis values from the application.properties.

To make it work, please do the following:

  1. Remove this bean definition:
@Bean
public LettuceConnectionFactory connectionFactory() {
    return new LettuceConnectionFactory();
}
  1. Define the RedisTemplate bean this way:
@Bean
public RedisTemplate<String, Object> deliveryRedisTemplate(RedisConnectionFactory connectionFactory) {
    RedisTemplate<String, Object> template = new RedisTemplate<>();
    template.setConnectionFactory(connectionFactory);
    return template;
}
  1. Define the following values in application.properties:
spring.redis.database=<replace-me>
spring.redis.host=<replace-me>
spring.redis.port=<replace-me>
spring.redis.timeout=<replace-me>
Protactinium answered 19/8, 2020 at 11:1 Comment(0)
I
3

I found the Heroku documentation for connecting to their Redis add-on (https://devcenter.heroku.com/articles/heroku-redis#connecting-in-java) contains an example using Jedis and therefore needed a little adaption. The content of the REDIS_URL added by Heroku to the environment of your running app resembles

redis://h:credentials@host:port

I parsed this using RedisURI.create and then set the host, port and password parameters of RedisStandaloneConfiguration

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

The code above is Kotlin rather than Java but perhaps it will help? You can find the full code at https://github.com/DangerousDarlow/springboot-redis

Indecision answered 11/1, 2020 at 1:1 Comment(0)
N
1

You need to choose between depending on autoconfiguration or defining your custom connection template.

First way is to remove HttpSessionConfig and then your redis properties from application.properties file will be applied. And as you have spring-redis-data-session dependency on your classpath your lettuce connection will be created implicitly.

Second solution is defining your connection properties as host, port, password inside LettuceConnectionFactory.

However it is recommended to use autoconfiguration.

Nickels answered 19/8, 2018 at 9:20 Comment(3)
Okay, so I tried both the methods. When I remove HttpSessonConfig, I get the error - org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded TomcatPickar
When I try to define the connection in the LettuceConnectionFactory, it gives me the same error.Pickar
You have posted too little error message to conclude answer and it is different problem so you should create another questtion.Nickels
M
1

Set the configuration in application.properties and 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);
            }
    }
Mirellamirelle answered 26/1, 2019 at 3:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.