Я настраиваю приложение Spring Boot 3 (с использованием Gradle и Java 17) с Redis Sentinel и клиентом Lettuce (нереактивным, с RedisTemplate).
Наша инфраструктурная группа предоставила установку Redis Sentinel (1 узел) с главным устройством и репликой, а также выделенным пользователем и паролем (+ACL). Однако при запуске приложения мы сталкиваемся с ошибкой проверки работоспособности.
PoolException: Could not get a resource from the pool
RedisConnectionException: Unable to connect to redis-sentinel://test:****@?sentinelMasterId=&timeout=3s
RedisCommandExecutionException: NOPERM User test has no permissions to run the 'sentinel|replicas' command.
Команда инфраструктуры подтверждает, что они намеренно ограничили эту команду, поскольку считают, что она служит реактивной цели, когда они обнаружили ошибку, которая не была исправлена в последних версиях...
Они также предложили настроить Lettuce так, чтобы она не использовала эту команду. Это правда?
Как настроить клиент Lettuce в нереактивном приложении Spring Boot для работы без необходимости разрешения SENTINEL REPLICAS? Существуют ли определенные настройки, такие как стратегия ReadFrom или альтернативный метод конфигурации, которые позволяют избежать этой команды?
Я уверен, что это стандартное поведение как в реактивном, так и в нереактивном режимах Lettuce, и вы не можете обойтись без этой команды.
Моя конфигурация: я использую стандартную конфигурацию RedisSentinelConfiguration для настройки LettuceConnectionFactory и ЧитатьFrom.Master.
@Configuration
@ConditionalOnProperty(prefix = "app.cache.redis", name = "enabled", havingValue = "true")
@RequiredArgsConstructor
@Slf4j
public class RedisConfig {
private final CustomRedisProperties customRedisProperties;
@Bean(destroyMethod = "shutdown")
public ClientResources clientResources() {
return DefaultClientResources.create();
}
@Bean
public ClientOptions clientOptions() {
return ClientOptions.builder()
.timeoutOptions(TimeoutOptions.enabled(Duration.ofMillis(customRedisProperties.getConnectTimeout())))
.disconnectedBehavior(DisconnectedBehavior.REJECT_COMMANDS)
.pingBeforeActivateConnection(true)
.autoReconnect(true)
.build();
}
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
return RedisCacheManager.RedisCacheManagerBuilder
.fromConnectionFactory(redisConnectionFactory)
.build();
}
@Bean
public GenericObjectPoolConfig redisPoolConfig() {
GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
genericObjectPoolConfig.setMaxTotal(customRedisProperties.getMaxActive());
genericObjectPoolConfig.setMaxIdle(customRedisProperties.getMaxIdle());
genericObjectPoolConfig.setMinIdle(customRedisProperties.getMinIdle());
genericObjectPoolConfig.setMaxWait(Duration.ofMillis(customRedisProperties.getMaxWait()));
genericObjectPoolConfig.setTestOnBorrow(true);
genericObjectPoolConfig.setTestWhileIdle(true);
genericObjectPoolConfig.setTimeBetweenEvictionRuns(Duration.ofSeconds(30));
genericObjectPoolConfig.setMinEvictableIdleDuration(Duration.ofSeconds(60));
genericObjectPoolConfig.setNumTestsPerEvictionRun(3);
return genericObjectPoolConfig;
}
@Bean
public LettuceClientConfiguration lettuceClientConfiguration(
GenericObjectPoolConfig redisPoolConfig,
ClientOptions clientOptions,
ClientResources clientResources
) {
return LettucePoolingClientConfiguration.builder()
.poolConfig(redisPoolConfig)
.clientOptions(clientOptions)
.clientResources(clientResources)
.commandTimeout(Duration.ofMillis(customRedisProperties.getCommandTimeout()))
.readFrom(ReadFrom.UPSTREAM) //ReadFrom.MASTER
.build();
}
@Bean
public RedisConnectionFactory redisConnectionFactory(
LettuceClientConfiguration lettuceClientConfiguration
) {
RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration();
sentinelConfig.master(customRedisProperties.getSentinel().getMaster());
if (Objects.nonNull(customRedisProperties.getSentinel().getPassword())) {
sentinelConfig.setSentinelPassword(RedisPassword.of(customRedisProperties.getSentinel().getPassword()));
}
if (Objects.nonNull(customRedisProperties.getSentinel().getUsername())) {
sentinelConfig.setSentinelUsername(customRedisProperties.getSentinel().getUsername());
}
if (customRedisProperties.getSupportUsername()
&& Objects.nonNull(customRedisProperties.getUsername())) {
sentinelConfig.setUsername(customRedisProperties.getUsername());
}
if (Objects.nonNull(customRedisProperties.getPassword())) {
sentinelConfig.setPassword(RedisPassword.of(customRedisProperties.getPassword()));
}
customRedisProperties.getSentinel().getNodes().forEach(node -> {
final var parts = node.split(":");
sentinelConfig.sentinel(parts[0], Integer.parseInt(parts[1]));
});
final var factory = new LettuceConnectionFactory(sentinelConfig, lettuceClientConfiguration);
factory.setShareNativeConnection(false);
factory.setValidateConnection(false);
return factory;
}
@Bean
public RedisTemplate redisTemplate(
RedisConnectionFactory redisConnectionFactory,
ObjectMapper objectMapper) {
RedisTemplate template = new RedisTemplate();
final var serializer = new Jackson2JsonRedisSerializer(objectMapper, Object.class);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(serializer);
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(serializer);
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
Подробнее здесь: https://stackoverflow.com/questions/797 ... n-user-lac
Spring Boot 3 с Lettuce: как избежать команды SENTINEL REPLICAS, когда у пользователя нет разрешений? ⇐ JAVA
Программисты JAVA общаются здесь
1760632807
Anonymous
Я настраиваю приложение Spring Boot 3 (с использованием Gradle и Java 17) с Redis Sentinel и клиентом Lettuce (нереактивным, с RedisTemplate).
Наша инфраструктурная группа предоставила установку Redis Sentinel (1 узел) с главным устройством и репликой, а также выделенным пользователем и паролем (+ACL). Однако при запуске приложения мы сталкиваемся с ошибкой проверки работоспособности.
PoolException: Could not get a resource from the pool
RedisConnectionException: Unable to connect to redis-sentinel://test:****@?sentinelMasterId=&timeout=3s
RedisCommandExecutionException: NOPERM User test has no permissions to run the 'sentinel|replicas' command.
Команда инфраструктуры подтверждает, что они намеренно ограничили эту команду, поскольку считают, что она служит реактивной цели, когда они обнаружили ошибку, которая не была исправлена в последних версиях...
Они также предложили настроить Lettuce так, чтобы она не использовала эту команду. Это правда?
Как настроить клиент Lettuce в нереактивном приложении Spring Boot для работы без необходимости разрешения SENTINEL REPLICAS? Существуют ли определенные настройки, такие как стратегия ReadFrom или альтернативный метод конфигурации, которые позволяют избежать этой команды?
Я уверен, что это стандартное поведение как в реактивном, так и в нереактивном режимах Lettuce, и вы не можете обойтись без этой команды.
Моя конфигурация: я использую стандартную конфигурацию RedisSentinelConfiguration для настройки LettuceConnectionFactory и ЧитатьFrom.Master.
@Configuration
@ConditionalOnProperty(prefix = "app.cache.redis", name = "enabled", havingValue = "true")
@RequiredArgsConstructor
@Slf4j
public class RedisConfig {
private final CustomRedisProperties customRedisProperties;
@Bean(destroyMethod = "shutdown")
public ClientResources clientResources() {
return DefaultClientResources.create();
}
@Bean
public ClientOptions clientOptions() {
return ClientOptions.builder()
.timeoutOptions(TimeoutOptions.enabled(Duration.ofMillis(customRedisProperties.getConnectTimeout())))
.disconnectedBehavior(DisconnectedBehavior.REJECT_COMMANDS)
.pingBeforeActivateConnection(true)
.autoReconnect(true)
.build();
}
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
return RedisCacheManager.RedisCacheManagerBuilder
.fromConnectionFactory(redisConnectionFactory)
.build();
}
@Bean
public GenericObjectPoolConfig redisPoolConfig() {
GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
genericObjectPoolConfig.setMaxTotal(customRedisProperties.getMaxActive());
genericObjectPoolConfig.setMaxIdle(customRedisProperties.getMaxIdle());
genericObjectPoolConfig.setMinIdle(customRedisProperties.getMinIdle());
genericObjectPoolConfig.setMaxWait(Duration.ofMillis(customRedisProperties.getMaxWait()));
genericObjectPoolConfig.setTestOnBorrow(true);
genericObjectPoolConfig.setTestWhileIdle(true);
genericObjectPoolConfig.setTimeBetweenEvictionRuns(Duration.ofSeconds(30));
genericObjectPoolConfig.setMinEvictableIdleDuration(Duration.ofSeconds(60));
genericObjectPoolConfig.setNumTestsPerEvictionRun(3);
return genericObjectPoolConfig;
}
@Bean
public LettuceClientConfiguration lettuceClientConfiguration(
GenericObjectPoolConfig redisPoolConfig,
ClientOptions clientOptions,
ClientResources clientResources
) {
return LettucePoolingClientConfiguration.builder()
.poolConfig(redisPoolConfig)
.clientOptions(clientOptions)
.clientResources(clientResources)
.commandTimeout(Duration.ofMillis(customRedisProperties.getCommandTimeout()))
.readFrom(ReadFrom.UPSTREAM) //ReadFrom.MASTER
.build();
}
@Bean
public RedisConnectionFactory redisConnectionFactory(
LettuceClientConfiguration lettuceClientConfiguration
) {
RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration();
sentinelConfig.master(customRedisProperties.getSentinel().getMaster());
if (Objects.nonNull(customRedisProperties.getSentinel().getPassword())) {
sentinelConfig.setSentinelPassword(RedisPassword.of(customRedisProperties.getSentinel().getPassword()));
}
if (Objects.nonNull(customRedisProperties.getSentinel().getUsername())) {
sentinelConfig.setSentinelUsername(customRedisProperties.getSentinel().getUsername());
}
if (customRedisProperties.getSupportUsername()
&& Objects.nonNull(customRedisProperties.getUsername())) {
sentinelConfig.setUsername(customRedisProperties.getUsername());
}
if (Objects.nonNull(customRedisProperties.getPassword())) {
sentinelConfig.setPassword(RedisPassword.of(customRedisProperties.getPassword()));
}
customRedisProperties.getSentinel().getNodes().forEach(node -> {
final var parts = node.split(":");
sentinelConfig.sentinel(parts[0], Integer.parseInt(parts[1]));
});
final var factory = new LettuceConnectionFactory(sentinelConfig, lettuceClientConfiguration);
factory.setShareNativeConnection(false);
factory.setValidateConnection(false);
return factory;
}
@Bean
public RedisTemplate redisTemplate(
RedisConnectionFactory redisConnectionFactory,
ObjectMapper objectMapper) {
RedisTemplate template = new RedisTemplate();
final var serializer = new Jackson2JsonRedisSerializer(objectMapper, Object.class);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(serializer);
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(serializer);
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79791556/spring-boot-3-with-lettuce-how-to-avoid-sentinel-replicas-command-when-user-lac[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия