【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 和端口。

参考资料

相关推荐
Mahir087 小时前
Spring 循环依赖深度解密:从问题本质到三级缓存源码级解析
java·后端·spring·缓存·面试·循环依赖·三级缓存
曲幽7 小时前
我用了FastApiAdmin后,连夜把踩过的坑都整理出来了
redis·python·postgresql·vue3·fastapi·web·sqlalchemy·admin·fastapiadmin
RyFit9 小时前
SpringAI 常见问题及解决方案大全
java·ai
石山代码9 小时前
C++ 内存分区 堆区
java·开发语言·c++
绝知此事9 小时前
【算法突围 01】线性结构与哈希表:后端开发的收纳术
java·数据结构·算法·面试·jdk·散列表
无风听海9 小时前
C# 隐式转换深度解析
java·开发语言·c#
一只大袋鼠10 小时前
Git 进阶(二):分支管理、暂存栈、远程仓库与多人协作
java·开发语言·git
德思特11 小时前
从 Dify 配置页理解 RAG 的重要参数
java·人工智能·llm·dify·rag
YOU OU11 小时前
Spring IoC&DI
java·数据库·spring
один but you11 小时前
从可变参数到 emplace:现代 C++ 性能优化的核心组合
java·开发语言