Spring Boot多实例Redisson分布式锁本地连接问题求助
一、本地Redis集群连接Redisson的错误排查与修复
针对ClusterStateFailureException: Could not retrieve cluster information. CLUSTER NODES returned with error.错误,按以下步骤逐一排查:
核对Redisson集群配置格式
确保配置文件正确指定所有集群节点地址,以YAML配置为例:singleServerConfig: idleConnectionTimeout: 10000 connectTimeout: 10000 timeout: 3000 clusterServersConfig: idleConnectionTimeout: 10000 connectTimeout: 10000 timeout: 3000 nodeAddresses: - "redis://127.0.0.1:7000" - "redis://127.0.0.1:7001" - "redis://127.0.0.1:7002" - "redis://127.0.0.1:7003" - "redis://127.0.0.1:7004" - "redis://127.0.0.1:7005" scanInterval: 1000若集群设置了密码,需在
clusterServersConfig下添加password: "你的密码"。确认本地Redis集群状态正常
执行命令redis-cli -p 7000 cluster nodes,检查所有节点状态为connected,主从关系无异常,无fail状态节点。若有节点故障,先修复集群再连接Redisson。匹配Spring Boot与Redisson版本
版本不兼容会导致通信异常:- Spring Boot 2.7.x 对应 Redisson 3.19.x
- Spring Boot 3.x 对应 Redisson 3.23+
Maven依赖示例:
<dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId> <version>3.23.3</version> </dependency>开放集群相关端口
本地防火墙可能拦截Redis集群端口(默认7000-7005),以及节点内部通信端口(节点端口+10000,如7000对应17000),确保这些端口对外放行。禁用DNS解析(本地测试用)
若集群节点配置了主机名,Redisson可能解析出错,在配置中添加:clusterServersConfig: dnsMonitoringInterval: 0
二、远程Redis集群证书问题临时处理
针对CertificateException: No subject alternative names matching IP address 12.23.23.23 found错误:
将证书导入JVM信任库
找到JVM的cacerts文件(路径一般为$JAVA_HOME/jre/lib/security/cacerts),执行导入命令:keytool -import -alias redis-cluster-cert -file /path/to/你的证书.pem -keystore $JAVA_HOME/jre/lib/security/cacerts默认密码为
changeit。临时禁用端点验证(仅测试)
紧急测试时可在Redisson配置中添加:clusterServersConfig: sslEnableEndpointIdentification: false生产环境必须开启此验证,建议联系运维更新证书,添加对应IP的主题备用名称(SAN)。
三、任务A的分布式锁实现示例
本地Redisson运行正常后,实现任务A的防重复执行逻辑:
@Service public class TaskAService { @Autowired private RedissonClient redissonClient; public void runTaskA() { RLock lock = redissonClient.getLock("task:A:lock"); try { // 最多等待5秒获取锁,锁自动释放时间30秒(可自定义TTL) if (lock.tryLock(5, 30, TimeUnit.SECONDS)) { // 任务A业务逻辑 System.out.println("任务A开始执行"); Thread.sleep(10000); // 模拟任务运行 System.out.println("任务A执行完成"); } else { System.out.println("任务A正在运行,拒绝重复触发"); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { if (lock.isHeldByCurrentThread()) { lock.unlock(); } } } }
内容的提问来源于stack exchange,提问作者Divyanshu Singh

