O seguinte erro pode ocorrer ao utilizar o cliente Lettuce em um ambiente de cluster Redis:
java.lang.IllegalArgumentException: Connection to 192.168.60.59:7001 not allowed. This connection point is not known in the cluster view
Essa exceção, muitas vezes envolta por um RedisException, indica que o cliente está tentando se conectar a um endereço IP e porta (nó) que não faz parte da visão atual do cluster que ele conhece. O Lettuce mantém um mapa da topologia do cluster, atualizado periodicamente ou sob demanda, e proíbe conexões para nós desconhecidos como uma medida de segurança para evitar redirecionamentos inválidos ou ataques.
A situação costuma surgir quando a topologia do cluster muda (por exemplo, durante uma operação de failover ou adição/remoção de um nó) e a visão do cliente ainda não foi atualizada. O Lettuce carrega a topologia inicial na primeira conexão. Para mitigar esse problema, é recomendável habilitar a atualização adapttaiva da topologia ou, como alternativa menos segura, desabilitar a validação rigorosa dos nós do cluster.
Um exemplo de configuração para Spring Boot que habilita a atualização adaptativa da topologia baseada em certos gatilhos pode ser implementado como mostrado abaixo. Note que a estrutura e os nomes das variáveis foram alterados em relação a exepmlos comuns para ilustrar uma implementação diferente, mas funcional:
import io.lettuce.core.cluster.ClusterTopologyRefreshOptions;
import io.lettuce.core.cluster.ClusterClientOptions;
import io.lettuce.core.ClientOptions;
import org.springframework.boot.autoconfigure.data.redis.LettuceClientConfigurationBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ConditionalOnClass;
import org.springframework.context.annotation.Configuration;
import java.time.Duration;
import java.util.HashSet;
import java.util.Set;
@Configuration
@ConditionalOnClass(ClusterTopologyRefreshOptions.class)
public class ClusterRefreshConfig {
@Bean
@ConditionalOnMissingBean
public LettuceClientConfigurationBuilderCustomizer redisClusterCustomizer() {
return builder -> {
// Define os gatilhos para atualização da topologia
Set<ClusterTopologyRefreshOptions.RefreshTrigger> triggerSet = new HashSet<>();
triggerSet.add(ClusterTopologyRefreshOptions.RefreshTrigger.MOVED_REDIRECT);
triggerSet.add(ClusterTopologyRefreshOptions.RefreshTrigger.ASK_REDIRECT);
triggerSet.add(ClusterTopologyRefreshOptions.RefreshTrigger.PERSISTENT_RECONNECTS);
triggerSet.add(ClusterTopologyRefreshOptions.RefreshTrigger.UNKNOWN_NODE);
// Configura as opções de atualização da topologia
ClusterTopologyRefreshOptions refreshConfig = ClusterTopologyRefreshOptions.builder()
.enableAdaptiveRefreshTrigger(triggerSet)
.adaptiveRefreshTriggersTimeout(Duration.ofSeconds(30))
.enableAllClusterViews()
.build();
// Constrói as opções avançadas do cliente com a atualização de topologia
ClientOptions clusterClientOptions = ClusterClientOptions.builder()
.topologyRefreshOptions(refreshConfig)
.build();
builder.clientOptions(clusterClientOptions);
};
}
}
Esta abordagem faz com que o cliente Lettuce solicite uma atualização da topologia do cluster quando encontrar redirecionamentos MOVED ou ASK, ao tentar se reconectar a um nó de forma persistente, ou ao tentar se comunicar com um nó desconhecido.