用 Spring Boot 3.X 的朋友,大概率都见过这条报错:Unable to connect to Redis。说它难排查吧,本质就是个连接失败;说它简单吧,从配置前缀到客户端行为,从服务端 bind 到连接池耗尽,每个环节都可能埋雷。这篇文章我就把实际踩坑、排查、解决的过程完整记录下来,顺便把 Spring Boot 3 时代连接 Redis 的几个经典误区和验证方法一次说清楚。
不管你是刚从 Spring Boot 2.x 升级上来的,还是新项目第一次集成 Redis,只要报错里带 Unable to connect to Redis、RedisConnectionFailureException 或者 Connection refused,这篇文章都值得你照着过一遍。
1. 先看懂异常栈:Unable to connect to Redis 到底被什么触发
很多新手看到 Unable to connect to Redis 后面那一大坨异常栈就直接懵了,其实真正有用的信息就藏在几个关键行里。我先拿一次典型的报错现场拆给你看。
1.1 完整报错长什么样
下面这段异常是我在一台测试环境上实际抓到的,Spring Boot 3.2.5 + spring-boot-starter-data-redis,配置项只写了 host 和 port:
plaintext复制org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.afterPropertiesSet(LettuceConnectionFactory.java:200)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(...)
...
Caused by: io.lettuce.core.RedisConnectionException: Unable to connect to localhost/127.0.0.1:6379
at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:78)
at io.lettuce.core.AbstractRedisClient.connect(AbstractRedisClient.java:216)
at io.lettuce.core.RedisClient.connect(RedisClient.java:202)
...
Caused by: java.net.ConnectException: Connection refused: /127.0.0.1:6379
at java.base/sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:714)
...
第一行 RedisConnectionFailureException 是 Spring Data Redis 包装出来的上层异常,基本等于告诉你“Redis 连接这条路不通”。真正的原因是下面这两行:
io.lettuce.core.RedisConnectionException: Unable to connect to localhost/127.0.0.1:6379:这里会明确写出 Lettuce 尝试连接的地址和端口,也就是当前配置实际生效的地址。如果你发现它连的是localhost/127.0.0.1,而你明明配置的是远程 IP,那就说明配置没有生效。java.net.ConnectException: Connection refused: /127.0.0.1:6379:这才是最底层的网络原因。Connection refused说明 TCP 连接被目标主机拒绝了,通常意味着目标端口没有进程在监听,或者防火墙直接回了 RST。
所以第一步不是急着改代码,而是先按住异常栈,把「目标地址 + 底层异常类型」这两个信息摘出来。地址看第二层 Caused by,底层原因看最内层 Caused by。这两行定位清楚了,后面排查就有的放矢。
1.2 报错关键词速查表
我把实际工作中高频遇到的异常关键词整理成了下面这张表,可以直接对着查:
| 异常关键字 | 含义 | 常见场景 |
|---|---|---|
Connection refused: /127.0.0.1:6379 |
TCP 连接被拒绝,端口无人监听或防火墙拒绝 | Redis 服务没启动、端口写错、连错主机 |
Connection timed out |
TCP 连接超时,包发出去没响应 | 网络不通、防火墙 DROP、跨网段不可达 |
NOAUTH Authentication required |
服务端要求密码,但客户端没带密码 | Redis 配了 requirepass,客户端没配 password |
ERR Client sent AUTH, but no password is set |
客户端带了密码,但服务端根本没设置密码 | Redis 没配 requirepass,客户端却填了密码 |
WRONGPASS invalid username-password pair |
密码错误或用户被禁用 | requirepass 密码填错、ACL 用户权限不对 |
Command timed out after 3 second(s) |
命令发送超时,连接建立但服务端响应慢 | 慢查询、网络丢包、连接池耗尽 |
Cannot get connection from pool |
连接池拿不到连接 | 连接池耗尽、连接泄漏、Lettuce 断线未恢复 |
这张表不是让你背,而是排查时养成一个习惯:先看 Caused by 链路最内层的异常类型,再决定走哪条排查路径。Connection refused 和 Connection timed out 虽然都叫“连不上”,但一个是“对方明确拒绝”,一个是“对方没有回应”,两者对应的排查方向完全不同。
1.3 为什么连接错误往往到了运行期才暴露
还有一个让很多人困惑的点:明明 Redis 连不上,为什么项目启动时没报错,等接口一调才炸出来?这跟 Spring Boot 3 的自动配置机制有关。
Spring Data Redis 的 LettuceConnectionFactory 默认是懒初始化连接,也就是说,创建连接工厂的时候不会立刻去连 Redis,只有第一次真正执行 Redis 命令时才会建立底层连接。除非你有健康检查、ApplicationRunner 里主动调用 Redis,或者配置了 spring.data.redis.repositories.enabled 等会触发初始化的选项,否则启动阶段大概率是“安全”的。
这带来的后果是:配置写错了,项目照样能启动,等到第一个请求打到缓存或者 Session 上,Unable to connect to Redis 才姗姗来迟。我建议在项目里加一个启动自检,把问题前置到启动阶段,后面第 5 章会给出具体写法。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Spring Boot 3.x 配置迁移:spring.redis 到 spring.data.redis,被静默忽略的坑
如果你是从 Spring Boot 2.x 升到 3.x 的老项目,Unable to connect to Redis 这个报错有相当大概率是配置前缀迁移导致的。这个坑的特殊之处在于:配置失效不是报错,而是被静默忽略。
2.1 为什么 Spring Boot 3 要换配置前缀
Spring Boot 2.x 时代,Redis 的配置前缀是 spring.redis.*,比如 spring.redis.host、spring.redis.port。从 Spring Boot 3.0 开始,官方对配置属性做了大规模整理,把多个数据源相关的配置统一收拢到 spring.data.* 命名空间下,Redis 从 spring.redis 变成了 spring.data.redis。
这个改动的初衷是为了让配置结构更统一,避免 spring.redis 和 spring.data.* 像两套系统各管各的。但对升级项目来说,问题在于:当你还在用 spring.redis.host 时,Spring Boot 3 根本不会报配置错误,只是不识别这个属性,然后静默使用默认值 localhost:6379。
于是你看到的现象就是:配置文件里明明写了远程 Redis 地址,启动也不报错,真正调接口时却提示 Unable to connect to localhost/127.0.0.1:6379。如果你在异常栈第二层看到连接地址是 localhost,优先怀疑配置前缀。
2.2 新旧配置对照表
下面这张表是我整理的常用配置项迁移对照,建议直接复制到项目的升级笔记里:
| Spring Boot 2.x 配置项 | Spring Boot 3.x 配置项 | 作用 |
|---|---|---|
spring.redis.host |
spring.data.redis.host |
Redis 服务地址 |
spring.redis.port |
spring.data.redis.port |
Redis 服务端口 |
spring.redis.password |
spring.data.redis.password |
Redis 密码 |
spring.redis.database |
spring.data.redis.database |
数据库索引(默认 0) |
spring.redis.timeout |
spring.data.redis.timeout |
读写超时时间 |
spring.redis.lettuce.pool.max-active |
spring.data.redis.lettuce.pool.max-active |
连接池最大活跃连接数 |
spring.redis.lettuce.pool.max-idle |
spring.data.redis.lettuce.pool.max-idle |
连接池最大空闲连接数 |
spring.redis.jedis.pool.max-active |
spring.data.redis.jedis.pool.max-active |
Jedis 连接池配置(如用 Jedis) |
spring.redis.cluster.nodes |
spring.data.redis.cluster.nodes |
集群节点配置 |
spring.redis.sentinel.master |
spring.data.redis.sentinel.master |
哨兵主节点名称 |
拿一个比较完整的配置举例,Spring Boot 3 下的标准写法是:
yaml复制spring:
data:
redis:
host: 192.168.1.100
port: 6379
password: yourpassword
database: 0
timeout: 3s
lettuce:
pool:
enabled: true
max-active: 16
max-idle: 8
min-idle: 2
注意 lettuce.pool.enabled: true 这个配置,Spring Boot 2.x 里连接池默认是开启的,但 3.x 里如果你没有显式引入 commons-pool2 依赖,即使配了 max-active 也不会生效,甚至可能在启动时报找不到 GenericObjectPool 相关的类。后面第 4 章会细说。
2.3 迁移时容易忽略的三个细节
第一个细节是 timeout 的写法。新旧版本的 timeout 都支持 Duration 写法,比如 3s、500ms,也可以写成纯数字。但注意如果你写的是 spring.data.redis.timeout: 3000,在 Spring Boot 3 里会被解析为 3000 纳秒,而不是 3000 毫秒。这个坑我见过不止一次,配置超时一定要带单位,推荐直接写 3s。
第二个细节是密码为空的情况。如果 Redis 服务端没有设置密码,spring.data.redis.password 就不要配置,或者配置为空字符串。有时候从旧项目迁移过来,配置里残留了一个空的 password: "",Lettuce 会试图发送 AUTH 命令,服务端没设置密码就会返回 ERR Client sent AUTH, but no password is set。
第三个细节是 Actuator 健康检查。如果你用了 spring-boot-starter-actuator,Redis 健康检查的配置项也从 management.health.redis.* 调整过。健康检查返回 DOWN 不一定代表 Redis 挂了,也可能是 health 检查时超时太短,试一下调长超时再观察。
3. Redis 服务端:为什么本机正常、项目连不上
配置前缀查完了,还连不上,就要把视野从应用代码切换到 Redis 服务端。这里有一条很常见的现象:本机用 redis-cli 连得好好的,项目一跑就 Connection refused。问题多半不在应用,而在 Redis 监听的地址和访问控制。
3.1 服务有没有起来,这条最快验证
排查服务端的第一步永远是确认 Redis 进程真的在跑,并且监听在正确的地址和端口上。不要凭“我记得启动过”来下结论,直接跑命令验证。
Linux / macOS 下:
bash复制# 查看 Redis 进程
ps -ef | grep redis-server
# 查看 6379 端口监听状态
ss -lntp | grep 6379
# 或者
netstat -lntp | grep 6379
Windows 下:
bash复制netstat -ano | findstr 6379
如果进程存在但端口没有监听,大概率是 redis.conf 里 port 被改掉了,或者 bind 配置导致只监听在某个特定 IP 上。ss -lntp 的输出里会显示 Redis 监听在哪个 IP,如果显示的是 127.0.0.1:6379,说明只监听了本机回环地址,外部 IP 自然连不上。
更直接的方式是本地执行:
bash复制redis-cli -h 127.0.0.1 -p 6379 ping
返回 PONG 说明服务端基本正常。如果返回 Could not connect to Redis,那问题就在服务端本身,先去翻 Redis 的启动日志,比如端口被占用、daemonize 配置、日志文件路径这些。
3.2 bind 与 protected-mode:最常见的“只能本地连”的根源
很多人在本地开发环境碰到的场景是:Redis 就在本机,应用也在本机,redis-cli 能 ping 通,但 Spring Boot 应用去连却报 Connection refused。我排查过这类问题,最后十有八九都是 bind 和 protected-mode 在作怪。
Redis 默认配置里 bind 127.0.0.1 -::1,意味着只监听在本地回环地址,任何从外部 IP 发起的连接都会被拒绝。如果你的 Spring Boot 应用和 Redis 不在同一台机器——比如应用在 Docker 容器里,Redis 在宿主机——那应用连的 127.0.0.1 是容器自己的回环地址,根本不是宿主机的 Redis。
解决办法是在 redis.conf 中调整 bind:
conf复制# 允许所有网卡访问(生产环境需配合防火墙限制)
bind 0.0.0.0
# 或者指定具体网卡 IP
bind 192.168.1.100 127.0.0.1
改完 bind 后重启 Redis,再用 ss -lntp 看监听地址是否变成目标 IP。
另一个容易忽略的是 protected-mode。Redis 默认 protected-mode yes,在没有设置密码且 bind 不是仅限本机的情况下,Redis 会拒绝外部主机的连接。这就是为什么很多人在云服务器上装了 Redis,本地 redis-cli 能连,远端却一直超时或者被拒。
有两种解决路径,我更推荐第二种:
- 直接把
protected-mode改成no。简单,但裸奔,不建议在非纯内网环境用。 - 给 Redis 设置密码(
requirepass),这样即使 protected-mode 开着,只要带了正确密码就能连。
记住一个原则:要么只监听内网/本机,要么设置强密码,别两个都不做就暴露到不可信网络。
3.3 密码、requirepass 与 ACL 账户体系
密码相关的报错在 Redis 连接问题里占比很高。这里说一下我实际遇到过的三类情况。
第一种,服务端设置了密码,客户端没配。启动和连接时出现 NOAUTH Authentication required,说明 Redis 要求认证但没收到密码。解决办法就是给客户端加上 spring.data.redis.password。
第二种,客户端配了密码,服务端没设置。报错是 ERR Client sent AUTH, but no password is set。这种情况出现在老项目升级时最典型,配置里还留着密码,但服务端的 Redis 是全新的、没配置 requirepass。去掉客户端配置,或者在服务端加上 requirepass,二选一。
第三种,密码配置了但不对。报错是 WRONGPASS invalid username-password pair or user is disabled。这里有个隐藏点:如果你用的是 Redis 6+ 的 ACL 体系,可能不是 requirepass 的密码错,而是 ACL 用户的问题。比如你用 default 用户登录,但 ACL 把 default 用户禁用了,或者 default 用户的密码和 requirepass 不一致。
检查服务端认证配置最快的方式:
bash复制# 进入 redis-cli 后执行
config get requirepass
config get protected-mode
# 查看 ACL 用户列表
acl list
# 用密码直接测试连接
redis-cli -h 127.0.0.1 -p 6379 -a yourpassword ping
注意 redis-cli -a 会暴露密码在 shell 历史记录里,测试完记得清一下,或者在命令前加空格(Linux 下部分 shell 不会记录以空格开头的命令)。更安全的做法是用环境变量 REDISCLI_AUTH=yourpassword redis-cli ping。
顺便说一句,排查这套时我习惯先用命令行工具把服务端认证走通,再去调 Spring Boot 配置。因为命令行工具能把“服务端认证规则”和“应用配置”这两层彻底分开,不在同一个问题上反复横跳。
4. Lettuce 连接池与网络侧:超时、断连、连接泄露的常见诱因
如果你确认服务端没问题、配置也正确,但应用偶尔连不上、偶尔超时,或者跑一段时间后突然报 Unable to connect to Redis,那就得关注客户端这一层了。Spring Boot 3 默认用的是 Lettuce,它的行为模式和 Jedis 差异不小,很多隐蔽问题都出在这里。
4.1 Lettuce 与 Jedis 的行为差异,连接池怎么配
Spring Boot 2.x 之后,默认的 Redis 客户端就是 Lettuce,依赖是 spring-boot-starter-data-redis 自带的。Lettuce 基于 Netty,连接是异步的、线程安全的,多个线程可以共享同一个连接,这是它和 Jedis 最大的不同。Jedis 实例不是线程安全的,所以需要连接池来管理。
Lettuce 默认并不强制使用连接池,一个连接就能扛住并发。但 Spring Boot 的自动配置还是提供了连接池支持,底层用的是 Apache Commons Pool 2。这里有个关键点:要启用连接池,必须先引入 commons-pool2 依赖,并且在配置里把 spring.data.redis.lettuce.pool.enabled 设为 true。
Maven 依赖示例:
xml复制<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
连接池配置示例:
yaml复制spring:
data:
redis:
lettuce:
pool:
enabled: true
max-active: 16
max-idle: 8
min-idle: 2
max-wait: 3s
如果你的应用是典型的高并发读多写少,建议 max-active 设置成略高于预估并发数,max-wait 不要给太长,否则连接池耗尽时请求会一直阻塞。我遇到过把 max-wait 配成 10 秒的情况,Redis 一抖动,整个接口全部卡死,看起来像应用假死。
如果你不想用 Lettuce,换成 Jedis 也简单,排除 Lettuce 再引入 Jedis:
xml复制<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
然后配置前缀改成 spring.data.redis.jedis.pool.*。说实话,在 Spring Boot 3 里我建议优先把 Lettuce 调好,而不是一遇到问题就换 Jedis。换客户端治标不治本,连接池耗尽、网络断连这些问题换个客户端照样会遇到。
4.2 超时与网络:Connection refused 与 timed out 是不同的故障域
前面说过,Connection refused 和 Connection timed out 是两个完全不同的故障域。实际排查时,很多人把这两个混在一起,导致方向跑偏。
Connection refused 的意思是目标主机收到了你的 TCP SYN 包,然后回了 RST。这说明网络是通的,但目标端口没有进程监听。常见原因:
- Redis 服务没启动或启动后又崩了
- Redis 监听端口和客户端配置端口不一致
- 防火墙对目标端口返回了 RST(较少见,多数防火墙是 DROP)
Connection timed out 的意思是 SYN 包发出去了,一直没收到响应。这说明包可能被丢弃了。常见原因:
- 防火墙 DROP 规则拦截
- 跨网段路由不通
- 云环境安全组没放行端口
- 目标主机负载过高,内核协议栈来不及响应
排查 Connection timed out 时,可以用 telnet 或 nc 快速验证端口连通性:
bash复制telnet 192.168.1.100 6379
# 或者
nc -vz 192.168.1.100 6379
如果 telnet 一直卡住,大概率是网络层问题,去查防火墙、安全组、路由。如果 telnet 显示 connected 但应用还是超时,那问题可能在应用侧,比如 Lettuce 的超时时间设置得太短。
Spring Boot 3 里 Redis 超时时间默认是 60 秒?不对,实际默认是 不超时,但 Spring Data Redis 的 timeout 不配置的话,Lettuce 底层有自己的默认超时。我建议显式配置一下,比如 3s,避免某个 Redis 慢操作把线程池拖垮:
yaml复制spring:
data:
redis:
timeout: 3s
4.3 连接池用尽与连接泄漏的表现
还有一类 Unable to connect to Redis 只在运行一段时间后出现,重启应用就好,过几天又犯。这种大概率是连接泄漏或者连接池耗尽。
Lettuce 虽然共享连接,但如果你大量使用事务、pipeline 或者阻塞命令,连接的状态管理就变得复杂。一旦某个连接因为网络抖动进入异常状态,Lettuce 没有及时重建,后续请求就可能拿不到可用连接。表现就是:线上报 Cannot get connection from pool 或者 Command timed out,但 Redis 服务端 info clients 看连接数并不多。
排查思路:
- 先看 Redis 服务端连接数:
redis-cli info clients - 再对比应用侧连接池配置的
max-active - 如果连接数接近
max-active且一直在涨,基本可以确定连接未释放
常见的连接泄漏场景有:
- 在事务里执行了阻塞命令,比如
BLPOP,超时时间设置不合理 - RedisTemplate 的
executePipelined使用不当,连接没归还 - 手动创建了
LettuceConnection但没有 close
我的一条经验是:尽量用 Spring Data Redis 提供的 RedisTemplate 和 StringRedisTemplate 的高级 API,不要频繁拿底层连接做自定义操作。高级 API 帮你管理了连接的生命周期,自己操作底层连接时一旦遗漏 close,就是隐形的泄漏源。
另外,Lettuce 和 Jedis 对连接池空闲连接的处理也不一样。Jedis 那边有 testWhileIdle、timeBetweenEvictionRunsMillis 这些兜底项,而 Lettuce 的 Spring Boot 配置里没有这些。换句话说,Lettuce 的池化连接如果被服务端断开,客户端可能感知不到,直到下一次真正使用才报错。这也是为什么有些连接问题“看起来像偶发”。
如果碰到这种情况,我建议在应用层加一个轻量的定时任务,定期执行 redisTemplate.getConnectionFactory().getConnection().ping(),把失效连接提前暴露出来;或者干脆用 spring.data.redis.lettuce.pool.max-active 控制上限,避免无限增长。
5. 一条可复制的完整排查链路与我的验证脚本
最后这部分,我想把前面所有排查点串成一条可复制的操作链路。以后不管在哪台机器上、哪个项目里再遇到 Unable to connect to Redis,照着这个顺序过一遍,基本都能定位到问题。
5.1 从报错关键字分流到排查动作
我习惯用下面这个判断顺序来分流:
第一步:看最内层 Caused by 异常类型。
Connection refused:走服务端检查链路,重点看 Redis 进程、端口监听、bind 配置。Connection timed out:走网络检查链路,重点看防火墙、安全组、路由、跨网段。NOAUTH/WRONGPASS/ERR Client sent AUTH:走认证检查链路,重点看 requirepass、ACL、客户端 password。Command timed out:走性能检查链路,重点看慢查询、网络质量、线程池配置。
第二步:用命令行直接测试 Redis 服务端可达性。
bash复制# 测网络端口
telnet 192.168.1.100 6379
# 或
nc -vz 192.168.1.100 6379
# 测认证
redis-cli -h 192.168.1.100 -p 6379 ping
redis-cli -h 192.168.1.100 -p 6379 -a yourpassword ping
命令行能通,问题在应用配置;命令行不通,问题在服务端或网络。
第三步:确认 Spring Boot 3 配置前缀和依赖。
bash复制# 查看 effective 配置(适合用 spring-boot-maven-plugin 启动时)
mvn spring-boot:run -Dspring-boot.run.arguments=--debug
# 或者启动时加 --debug 观察自动配置报告
java -jar app.jar --debug
--debug 输出里能找到 RedisAutoConfiguration、LettuceConnectionConfiguration 相关的 log,能看出当前生效的 Redis 配置来自哪里。这个技巧在定位“配置被静默忽略”时特别有用。
5.2 我在本机复现的一次完整过程
为了把整个排查链路讲得更直观,我拿自己实际遇到过的一次场景作为例子:项目中配置的是远程 Redis,启动正常,但调用时报 Unable to connect to localhost/127.0.0.1:6379。
排查过程如下:
- 先看异常栈,发现连接的地址是
localhost/127.0.0.1:6379,而我配置里写的是远程 IP,说明配置没生效。 - 打开配置文件,发现写的是
spring.redis.host,而不是spring.data.redis.host。这是典型的 Spring Boot 2.x 升级遗留问题。 - 改配置前缀为
spring.data.redis.host后重启,异常变成Connection timed out。 - 继续排查网络层,发现云安全组没放行 6379 端口。放行后 Redis 连接成功。
这个案例里三个问题嵌套在一起:配置前缀失效、网络不通、安全组没放行。如果不按链路一步步查,很可能纠结在第一个配置问题上浪费大量时间。
5.3 在项目里加一个启动自检 Bean,把问题前置
之前提过启动阶段默认不会连接 Redis,所以我习惯在项目里加一个启动自检。这样 Redis 配置对错、网络通不通,应用启动时立刻暴露,而不是等到第一个请求才炸。
代码很简单,用 ApplicationRunner 或者 CommandLineRunner 都可以:
java复制@Component
public class RedisStartupChecker implements ApplicationRunner {
private static final Logger log = LoggerFactory.getLogger(RedisStartupChecker.class);
private final StringRedisTemplate stringRedisTemplate;
public RedisStartupChecker(StringRedisTemplate stringRedisTemplate) {
this.stringRedisTemplate = stringRedisTemplate;
}
@Override
public void run(ApplicationArguments args) {
try {
String pong = stringRedisTemplate.getConnectionFactory()
.getConnection()
.ping();
log.info("Redis connection check passed, server response: {}", pong);
} catch (Exception e) {
log.error("Redis connection check failed: {}", e.getMessage(), e);
// 如果你希望启动失败就快速失败,可以在这里抛出异常
// throw new IllegalStateException("Redis connection check failed", e);
}
}
}
注意,getConnection() 拿到连接后,如果不做任何操作直接返回,有些版本下连接可能不会自动释放。更稳妥的做法是用现成的 RedisTemplate 执行一个命令,比如:
java复制stringRedisTemplate.hasKey("__startup_check__");
或者用 execute 回调让 Spring 帮你管理连接:
java复制stringRedisTemplate.execute((RedisCallback<String>) connection -> {
return connection.ping();
});
这段自检代码我在好几个项目里都用过,启动阶段检查完再往外暴露服务,比上线后才发现连不上 Redis 要从容得多。
如果说还有什么想额外提醒的,那就是:一旦遇到 Redis 连不上,不要反复改配置重启碰运气,先按异常类型分流,再逐层验证。Redis 连接问题虽然表现形式单一,但根因往往在配置、网络、认证、客户端行为四个层面里互相叠加。把每一层都验证完,问题基本藏不住。这也是我写这篇记录的最大目的——希望你在下次遇到 Unable to connect to Redis 时,能少走一段弯路。
