最近项目上发现一个问题,redis cluster集群有一台机崩了之后,后台服务的redis会一直报错,无法连接到redis集群。通过命令查看redis集群,发现redis cluster集群是正常的,备用的slave机器已经升级为master。
于是初步猜测是spring-redis的连接池框架在redis的其中一台master机器崩了之后,并没有刷新连接池的连接,仍然连接的是挂掉的那台redis服务器。
通过寻找资料,发现springboot在1.x使用的是jedis框架,在2.x改为默认使用Lettuce框架与redis连接。 在Lettuce官方文档中找到了关于Redis Cluster的相关信息 《Refreshing the cluster topology view》
这里面的大概意思是 自适应拓扑刷新(Adaptive updates)与定时拓扑刷新(Periodic updates) 是默认关闭的,可以通过代码打开。
继续查找,发现了Lettuce官方给了开启拓扑刷新的代码例子
- # Example 37. Enabling periodic cluster topology view updates
- RedisClusterClient clusterClient = RedisClusterClient.create(RedisURI.create("localhost", 6379));
-
- ClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.builder()
- .enablePeriodicRefresh(10, TimeUnit.MINUTES)
- .build();
-
- clusterClient.setOptions(ClusterClientOptions.builder()
- .topologyRefreshOptions(topologyRefreshOptions)
- .build());
- ...
-
- clusterClient.shutdown();
-
-
- # Example 38. Enabling adaptive cluster topology view updates
- RedisURI node1 = RedisURI.create("node1", 6379);
- RedisURI node2 = RedisURI.create("node2", 6379);
-
- RedisClusterClient clusterClient = RedisClusterClient.create(Arrays.asList(node1, node2));
-
- ClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.builder()
- .enableAdaptiveRefreshTrigger(RefreshTrigger.MOVED_REDIRECT, RefreshTrigger.PERSISTENT_RECONNECTS)
- .adaptiveRefreshTriggersTimeout(30, TimeUnit.SECONDS)
- .build();
-
- clusterClient.setOptions(ClusterClientOptions.builder()
- .topologyRefreshOptions(topologyRefreshOptions)
- .build());
- ...
-
- clusterClient.shutdown();
- 复制代码
根据示例我们修改一下我们的项目代码
- import com.fasterxml.jackson.annotation.JsonAutoDetect;
- import com.fasterxml.jackson.