【BUG】Redisson Connection refused 127.0.0.1

Connection refused: no further information: 127.0.0.1/127.0.0.1:26379

问题背景

在开发一个基于 Spring Boot 的系统时,使用了 Redisson 作为 Redis 客户端连接 Redis Sentinel 集群。环境部署了一套 Redis Sentinel 集群(192.168.10.232/233/234)。然而,当启动 Spring Boot 应用时,却一直报连接错误。

错误现象

应用启动后,控制台持续输出以下错误日志:

复制代码
2026-01-27T10:26:04.283+08:00 ERROR [carry-test,,] 19316 --- [sson-netty-2-20] o.r.c.SentinelConnectionManager : io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: 127.0.0.1/127.0.0.1:26379 

java.util.concurrent.CompletionException: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: 127.0.0.1/127.0.0.1:26379 
 	 at java.base/java.util.concurrent.CompletableFuture.encodeRelay(CompletableFuture.java:368) ~[na:na] 
 	 at java.base/java.util.concurrent.CompletableFuture.completeRelay(CompletableFuture.java:377) ~[na:na] 
 	 at java.base/java.util.concurrent.CompletableFuture$UniRelay.tryFire(CompletableFuture.java:1097) ~[na:na] 
 	 at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510) ~[na:na] 
 	 at java.base/java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:2162) ~[na:na] 
 	 at org.redisson.client.RedisClient$2$2.run(RedisClient.java:325) ~[redisson-3.47.0.jar:3.47.0] 
 	 at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:173) ~[netty-common-4.1.130.Final.jar:4.1.130.Final] 
 	 at io.netty.util.concurrent.AbstractEventExecutor.safeExecute$$$capture(AbstractEventExecutor.java:166) ~[netty-common-4.1.130.Final.jar:4.1.130.Final] 
 	 at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java) ~[netty-common-4.1.130.Final.jar:4.1.130.Final] 
 	 at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472) ~[netty-common-4.1.130.Final.jar:4.1.130.Final] 
 	 at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569) ~[netty-transport-4.1.130.Final.jar:4.1.130.Final] 
 	 at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) ~[netty-common-4.1.130.Final.jar:4.1.130.Final] 
 	 at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.130.Final.jar:4.1.130.Final] 
 	 at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.130.Final.jar:4.1.130.Final] 
 	 at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na] 
 Caused by: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: 127.0.0.1/127.0.0.1:26379 
 Caused by: java.net.ConnectException: Connection refused: no further information 
 	 at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na] 
 	 at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na] 
 	 at java.base/sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:946) ~[na:na] 
 	 at io.netty.channel.socket.nio.NioSocketChannel.doFinishConnect(NioSocketChannel.java:336) ~[netty-transport-4.1.130.Final.jar:4.1.130.Final] 
 	 at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:339) ~[netty-transport-4.1.130.Final.jar:4.1.130.Final] 
 	 at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:784) ~[netty-transport-4.1.130.Final.jar:4.1.130.Final] 
 	 at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:732) ~[netty-transport-4.1.130.Final.jar:4.1.130.Final] 
 	 at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:658) ~[netty-transport-4.1.130.Final.jar:4.1.130.Final] 
 	 at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) ~[netty-transport-4.1.130.Final.jar:4.1.130.Final] 
 	 at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) ~[netty-common-4.1.130.Final.jar:4.1.130.Final] 
 	 at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.130.Final.jar:4.1.130.Final] 
 	 at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.130.Final.jar:4.1.130.Final] 
 	 at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na] 

Caused by: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: 127.0.0.1/127.0.0.1:26379 
Caused by: java.net.ConnectException: Connection refused: no further information

排查

源码分析

通过日志可以看到异常抛出点: at org.redisson.client.RedisClient$2$2.run(RedisClient.java:325) ~[redisson-3.47.0.jar:3.47.0]

通过调试 Redisson 源码,在 org.redisson.connection.SentinelConnectionManager#checkSentinelsChange 中可以确认,Redisson 会尝试连接 Sentinel 返回的所有节点。

java 复制代码
RFuture<List<Map<String, String>>> sentinelsFuture = connection.async(1, cfg.getRetryInterval(), cfg.getTimeout(),
                                        StringCodec.INSTANCE, RedisCommands.SENTINEL_SENTINELS, cfg.getMasterName());

这里通过 SENTINEL_SENTINELS 命令异步获取监控指定主节点的所有哨兵信息,用于动态发现和维护哨兵集群的连接信息。而返回的连接信息就存在127.0.0.1:26379


进一步验证猜想:

查看 Sentinel 节点列表

使用 SENTINEL SENTINELS 命令查看所有 Sentinel 节点:

bash 复制代码
redis-cli -h 192.168.10.232 -p 26379 SENTINEL SENTINELS mymaster

输出结果:

复制代码
1) "name"
2) "0cd34a64e7e9aa66f7db2950e4443690dc06fbe0"
3) "ip"
4) "192.168.10.233"
5) "port"
6) "26379"
...
1) "name"
2) "7e06af97bf0147e139b0d8b91856b1b5290b2ba1"
3) "ip"
4) "192.168.10.234"
5) "port"
6) "26379"
...

从 192.168.10.232 节点看,其他两个 Sentinel 节点的 IP 都是正确的。

再查看 192.168.10.233 节点的 Sentinel 列表:

bash 复制代码
redis-cli -h 192.168.10.233 -p 26379 SENTINEL SENTINELS mymaster

输出结果(关键部分):

复制代码
1) "name"
2) "fc1e6c82fd35196efba2acb8e55aeee965540b30"
3) "ip"
4) "192.168.10.232"
5) "port"
6) "26379"
...
1) "name"
2) "144ff2f46aa9333dc31e488a0606336fbf4da84b"
3) "ip"
4) "127.0.0.1"
5) "port"
6) "0"
7) "runid"
8) "144ff2f46aa9333dc31e488a0606336fbf4da84b"
9) "flags"
10) "s_down,sentinel,disconnected"
...
1) "name"
2) "0cd34a64e7e9aa66f7db2950e4443690dc06fbe0"
3) "ip"
4) "127.0.0.1"
5) "port"
6) "26379"
7) "runid"
8) "0cd34a64e7e9aa66f7db2950e4443690dc06fbe0"
9) "flags"
10) "sentinel"
...
1) "name"
2) "7e06af97bf0147e139b0d8b91856b1b5290b2ba1"
3) "ip"
4) "192.168.10.234"
5) "port"
6) "26379"
...

发现问题

从输出结果中,我们发现了两个异常的 Sentinel 节点:

  1. 节点 1

    • IP: 127.0.0.1
    • Port: 0
    • Flags: s_down,sentinel,disconnected
    • 状态:主观下线、已断开连接
  2. 节点 2

    • IP: 127.0.0.1
    • Port: 26379
    • Flags: sentinel
    • 状态:正常

这两个 Sentinel 节点使用了 127.0.0.1 作为 IP 地址,这是不正确的配置。

分析原因

当 Redisson 连接到 Sentinel 集群时,它会从 Sentinel 获取所有节点的信息,包括:

  • Master 节点
  • Slave 节点
  • 其他 Sentinel 节点

由于某些 Sentinel 节点配置了错误的 sentinel announce-ipreplica-announce-ip,导致它们向其他 Sentinel 注册时使用了 127.0.0.1

当 Redisson 尝试连接这些 127.0.0.1:26379 的节点时,就会报错 "Connection refused",因为:

  • 应用服务器不在 Redis 服务器本机上
  • 127.0.0.1 指向的是应用服务器自己,而不是 Redis 服务器

原因

  1. 配置文件sentinel.conf中设置了错误的 sentinel announce-ip
  2. redis.conf中设置了错误的replica-announce-ip
  3. 没配置依赖自动检测的本地 IP 和端口。

参考资料

相关推荐
兆子龙5 小时前
ahooks useRequest 深度解析:一个 Hook 搞定所有请求
java·javascript
兆子龙5 小时前
React Suspense 从入门到实战:让异步加载更优雅
java·javascript
咕白m6258 小时前
Java 实现 Excel 转 HTML:完整示例
java
RealPluto8 小时前
Spring AOP 失效排查
java·spring
码路飞9 小时前
热榜全是 OpenClaw,但我用 50 行 Python 就造了个桌面 AI Agent 🤖
java·javascript
Nyarlathotep01139 小时前
LinkedList源码分析
java·后端
用户8307196840829 小时前
Java 告别繁琐数据统计代码!MySQL 8 窗口函数真香
java·sql·mysql
带刺的坐椅9 小时前
SolonCode v0.0.20 发布 - 编程智能体(新增子代理和浏览器能力)
java·ai·agent·solon·solon-ai·claude-code·openclaw
会员源码网11 小时前
数字格式化陷阱:如何优雅处理 NumberFormatException
java