惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - Franky
D
Docker
Jina AI
Jina AI
The GitHub Blog
The GitHub Blog
博客园 - 聂微东
B
Blog RSS Feed
大猫的无限游戏
大猫的无限游戏
M
MIT News - Artificial intelligence
Vercel News
Vercel News
Microsoft Security Blog
Microsoft Security Blog
博客园 - 叶小钗
爱范儿
爱范儿
D
DataBreaches.Net
Hugging Face - Blog
Hugging Face - Blog
IT之家
IT之家
Recent Announcements
Recent Announcements
U
Unit 42
腾讯CDC
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
宝玉的分享
宝玉的分享
量子位
Stack Overflow Blog
Stack Overflow Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Microsoft Azure Blog
Microsoft Azure Blog

CAYZLH

Reasonix 开箱:聊聊我装的那些 Skill 收藏一份自驾中国的愿望清单 白夜行·谢幕 英雄联盟的昨日今天与符文大乱斗 折腾的尽头是极简 MacBook上备忘录APP的快捷键和手势 让Google屏蔽某些搜索结果 WSL自定义安装Ubuntu typora自动上传图片配置 自建giscus服务 Windows下结束指定端口的进程 批量修改maven多模块版本号 使用winsw部署SpringBoot项目 Gson简易指南 docker搭建Consul集群 使用Docker部署SpringBoot项目 Docker使用redis镜像 Docker使用rabbitmq Docker使用zookeeper Docker使用MySQL Dockerfile常用指令 Docker免sudo操作 雷鸟电视去广告 使用ADB卸载MIUI系统应用 利用GitHub做图床 将网站变成灰色 Github上传大文件 Android远程调试命令adb vscode快捷键的使用 SpringBoot文件上传异常处理
一个 `data.` 引发的血案——Redis 连接 localhost 问题排查全记录
Ant丶 · 2025-07-11 · via CAYZLH

背景

项目基于 Spring Boot 3.2.4 + Spring Cloud Alibaba + Nacos 配置中心,微服务架构,14 个服务模块。某天开始,所有服务在启动后日志中反复出现:

RedisReactiveHealthIndicator : Redis health check failed
Unable to connect to localhost/<unresolved>:6379

但 Redis 服务本身运行正常,网络可达,配置中也明确写了正确的连接地址。怪异之处在于,无论怎么改配置,Lettuce 都执着地连接 localhost:6379

第一阶段:怀疑配置覆盖

最初的分析方向是 Nacos 远程配置覆盖了本地配置。

项目的配置加载分为三层:

  1. 各服务 application.yml(打包在 jar 内)
  2. yuvex-common.yml(公共配置,通过 spring.config.import 引用)
  3. Nacos 远程配置(yuvex-cloud-bridge-config.yaml

怀疑 RedisProperties 绑定时机早于 Nacos 加载,导致拿到默认值 localhost,后续 Nacos 配置不重新绑定。于是尝试了以下方案:

  • 环境变量注入:在 Docker Compose 中设置 REDIS_HOSTSPRING_REDIS_HOST,利用环境变量高优先级覆盖
  • 占位符默认值${REDIS_HOST:yuvex-redis} 在 yuvex-common.yml 中作为兜底
  • 独立配置文件:将 Redis 配置提取到 redis-default.yml,通过 spring.config.import 最后加载

全部失败。容器里的 jar 明明有正确的配置,actuator /env 也显示 spring.redis.host 为正确值,但 health check 依然报 localhost

第二阶段:怀疑代码层问题

配置层面山穷水尽后,转入代码层排查。检查了所有自定义 Bean、自动配置排除、EnvironmentPostProcessor,甚至写了自定义 RedisConnectionDetails 替代 Spring Boot 默认实现——统统无效。

entrypoint 直接塞 -Dspring.redis.host JVM 系统属性,优先级在 Spring Boot 中排第二(仅次于命令行参数),理论上绝对无法被覆盖——仍然 localhost

这已经完全超出了常规认知。配置是对的,代码是干净的,JVM 参数是最高的,但连接地址就是 localhost

第三阶段:真相大白

在一次搜索中偶然看到一句话:

“I moved from spring.redis.host to spring.data.redis.host.”

立刻去查 Spring Boot 3.x 文档——Spring Boot 3.x 将 RedisProperties@ConfigurationProperties 前缀从 spring.redis 改成了 spring.data.redis

我们全程配置的 key 是 spring.redis.host,但 RedisProperties 绑定的是 spring.data.redis.host。因为找不到正确前缀的属性,RedisProperties.host 字段永远是其 Java 默认值——localhost

这就解释了所有反常现象:

  • /actuator/env/spring.redis.host 有值 → 那是 Environment 里的原始 key,不代表 RedisProperties 绑定了它
  • JVM 参数 -Dspring.redis.host 无效 → 同上
  • 环境变量 SPRING_REDIS_HOST 无效 → Relaxed Binding 映射到的还是错的 key

一切只差一个 data.

修复

将全部配置从 spring.redis.* 改为 spring.data.redis.*

# 错误(Spring Boot 3.x 不认这个前缀)
spring:
redis:
host: yuvex-redis

# 正确
spring:
data:
redis:
host: yuvex-redis

对应的环境变量从 SPRING_REDIS_HOST 改为 SPRING_DATA_REDIS_HOST

为什么 DataSource 不受影响

项目中数据库配置也用 spring.datasource,为什么没问题?因为 DataSourceProperties@ConfigurationProperties 前缀一直是 spring.datasource,Spring Boot 3.x 中没变。只有 Redis 被挪到了 spring.data 命名空间下。

总结

维度 反思
根因 Spring Boot 3.x 属性前缀变更——spring.redisspring.data.redis
为何排查了 8 次 每次都在配置加载机制上打转,忽略了属性的 key 是否被框架识别
验证盲区 /actuator/env 展示的是 Environment 原始值,不代表 @ConfigurationProperties 绑定结果
经验教训 升级主版本时,先查属性变更表,尤其是 @ConfigurationProperties 前缀

Spring Boot 3.x 属性变更参考:
https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html#appendix.application-properties.data