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();
}
}
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:
@Bean
public LettuceConnectionFactory connectionFactory() {
return new LettuceConnectionFactory();
}
@Bean
public RedisTemplate<String, Object> deliveryRedisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
return template;
}
application.properties
:spring.redis.database=<replace-me>
spring.redis.host=<replace-me>
spring.redis.port=<replace-me>
spring.redis.timeout=<replace-me>
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:
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;
}
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With