SpringBoot Redis удаленный хост
Я делаю приложение, которое использует Spring Boot, MySQL и Redis на Back End и Angular на Front End. Я хочу развернуть его в Heroku, чтобы использовать его с внешним интерфейсом, но я просто не могу настроить удаленный URL для Redis. У меня есть дополнение Redis To Go на Heroku для этого с готовым удаленным 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();
}
}
2 ответа
У меня была аналогичная проблема, вот как я ее решил:
Если вы определяете bean-компонент таким образом:
@Bean
public LettuceConnectionFactory connectionFactory() {
return new LettuceConnectionFactory();
}
Вы не разрешаете Spring брать значения Redis из application.properties
.
Чтобы он заработал, сделайте следующее:
- Удалите это определение bean-компонента:
@Bean
public LettuceConnectionFactory connectionFactory() {
return new LettuceConnectionFactory();
}
- Определите bean-компонент RedisTemplate следующим образом:
@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>
Я был разочарован той же самой проблемой, с которой вы сталкиваетесь, и документация или примеры весенней загрузки ничего не делают для решения того, с чем мы сталкиваемся. Причина, по которой ваши записи конфигурации не используются, заключается в том, что вы создаете новый экземпляр LettuceConnectionFactory с помощью конструктора без параметров. Копаясь в коде источника / байта, вы видите, что конструктор полностью игнорирует значения spring.redis.host и spring.redis.port и жестко их кодирует в localhost:6379.
То, что вы должны делать, это либо:
- Используйте конструктор LettuceConnectionFactory (имя хоста, порт).
- Не определяйте фабрику соединений. Избавьтесь от всей записи @Bean для connectionFactory(), и Spring автоматически соединит все и использует ваши записи конфигурации.
Также как примечание стороны; чтобы это работало с AWS Elasticache (локально через VPN), мне пришлось добавить к этому классу конфигурации:
@Bean
public static ConfigureRedisAction configureRedisAction() {
return ConfigureRedisAction.NO_OP;
}
Я обнаружил, что документация Heroku для подключения к их надстройке Redis (https://devcenter.heroku.com/articles/heroku-redis) содержит пример использования Jedis и поэтому требует небольшой адаптации. СодержаниеREDIS_URL
добавленный Heroku в среду вашего запущенного приложения, напоминает
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
Вам нужно выбрать между в зависимости от автоконфигурации или определения вашего пользовательского шаблона подключения.
Первый способ - удалить HttpSessionConfig
а затем ваши свойства Redis из application.properties
файл будет применен. И поскольку у вас есть зависимость spring-redis-data-session от вашего classpath, ваше соединение с салатом будет создано неявно.
Второе решение - определить свойства вашего соединения как хост, порт, пароль внутри LettuceConnectionFactory
,
Однако рекомендуется использовать автоконфигурацию.
Задайте конфигурацию в файле 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);
}
}