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

参考资料

相关推荐
三8445 小时前
redis防御加固与安全基线
数据库·redis·安全·应急响应·防御
lhldsg5 小时前
全民健身解决方案小程序开发:从0到1的技术实战
java·数据库·需求分析
jason成都5 小时前
Spring WebFlux 适配达梦新方案|dm‑r2dbc:Netty 异步传输的实验性 R2DBC 驱动
java·后端·spring
SendTomo5 小时前
【技术交流】从0到1构建一个汉字学习平台:汉字吧(hanzi8.com)的技术架构猜想
redis·mysql·nginx·php·个人开发
泡海椒5 小时前
内置SPI函数库详解:JQuick-Java Builtin工具类实战用法
java·开发语言·python
辰烨chenye6 小时前
LeetCode Hot 100 题解 · 二分篇
java·算法·leetcode
小羊没烦恼!6 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
小荷才露尖尖角,早有蜻蜓立上头7 小时前
过滤器的4种创建方式
java
大圣编蚕7 小时前
Java ByteArrayInputStream 详解:从入门到实战
java·开发语言·算法
程序员阿明8 小时前
idea把插件啥的不默认放在C盘
java·ide·intellij-idea