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.

Чтобы он заработал, сделайте следующее:

  1. Удалите это определение bean-компонента:
@Bean
public LettuceConnectionFactory connectionFactory() {
    return new LettuceConnectionFactory();
}
  1. Определите bean-компонент RedisTemplate следующим образом:
@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>

Я был разочарован той же самой проблемой, с которой вы сталкиваетесь, и документация или примеры весенней загрузки ничего не делают для решения того, с чем мы сталкиваемся. Причина, по которой ваши записи конфигурации не используются, заключается в том, что вы создаете новый экземпляр 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);
            }
    }
Другие вопросы по тегам