Spring Boot 接入 Redis Sentinel:自动主从切换与读写分离实战(修复单机多实例与 Sentinel 配置坑)
文章目录
- 一、环境说明
- 二、修复前两篇遗留的坑(并且打开防火墙7001/2/3,27001/2/3)
- 1. Redis 实例(主从)需指定对外公告地址
- 2. Sentinel 需指定对外公告地址
- 3. 刷新 Sentinel 配置
- 三、Spring Boot 应用接入配置
- 1. 依赖
- 2. application.yml
- 3. 开启 Lettuce 读写分离策略
- 4. 示例接口
- 四、正常运行验证
- 五、故障切换实战(模拟主库宕机)
- 1. 主库下线
- 2. Spring Boot 日志分析
- (1) 读写异常触发
- (2) 客户端自动重连
- (3) 写请求切换到新主库
- 3. 验证结果
- 六、总结与闭环
前两篇我们已经完成了:
- 第一篇:《Redis单机多实例集群实战指南》 👉 在一台机器上运行多个 Redis 实例(7001 主 + 7002/7003 从),构建主从环境。
- 第二篇:《手把手搭建 Redis Sentinel 高可用集群》 👉 在主从之上增加三哨兵(27001/27002/27003),实现自动故障转移。
但如果你直接用这两个环境去接入 Spring Boot 应用,会遇到连接报错:
Unable to connect to 127.0.0.1:7002 Unable to connect to 127.0.0.1:7003
原因就在于前两篇的配置对外广播了错误的 IP(127.0.0.1)。本文将带你修复这些坑,并完成 Spring Boot 应用接入 Redis Sentinel,实现自动主从切换与读写分离。
一、环境说明
- Redis 主从:7001(主)、7002(从)、7003(从)
- Sentinel 集群:27001、27002、27003
- Redis 密码:
1111
(示例) - Spring Boot:基于
spring-data-redis
(Lettuce 驱动)
二、修复前两篇遗留的坑(并且打开防火墙7001/2/3,27001/2/3)
1. Redis 实例(主从)需指定对外公告地址
在 redis.conf
中添加:
replicaof 192.168.1.100 7003 # 改成真实宿主机以及对应端口
主节点(7001)也建议修改:
replicaof 192.168.1.100 7003 # 改成真实宿主机以及对应端口
2. Sentinel 需指定对外公告地址
在每个 sentinel.conf
中添加:
sentinel announce-ip 192.168.1.100 # 27002 / 27003 分别改
3. 刷新 Sentinel 配置
修改配置后,在每个 Sentinel 上执行:
redis-cli -h 192.168.1.100 -p 27001 SENTINEL RESET mymaster
redis-cli -h 192.168.1.100 -p 27001 SENTINEL flushconfig
执行后,检查:
redis-cli -h 192.168.1.100 -p 27001 SENTINEL slaves mymaster
输出里的 ip=
字段应为真实 IP,而不是 127.0.0.1
。
这样,应用端才能获取正确的拓扑。
三、Spring Boot 应用接入配置
1. 依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2. application.yml
spring:redis:sentinel:master: mymasternodes:- 192.168.1.100:27001- 192.168.1.100:27002- 192.168.1.100:27003password: 1111timeout: 3000
3. 开启 Lettuce 读写分离策略
/*** @author: takumilove* @description: Redis 配置类* @date: 2025/9/23**/
@Configuration
@ConditionalOnClass(ReadFrom.class)
public class RedisConfig {/*** Lettuce 配置:读写分离,固定使用 REPLICA_PREFERRED*/@Beanpublic LettuceClientConfigurationBuilderCustomizer lettuceReadFromCustomizer() {return builder -> builder.readFrom(ReadFrom.REPLICA_PREFERRED);}
}
4. 示例接口
@RestController
public class HelloController {@Autowiredprivate StringRedisTemplate redisTemplate;@GetMapping("/set/{key}/{value}")public String set(@PathVariable String key, @PathVariable String value) {redisTemplate.opsForValue().set(key, value);return "OK";}@GetMapping("/get/{key}")public String get(@PathVariable String key) {return redisTemplate.opsForValue().get(key);}
}
四、正常运行验证
curl "http://localhost:8080/set/hello/world"
curl "http://localhost:8080/get/hello"
-
写操作走 master(7001)
-
读操作走 replica(7002/7003)
五、故障切换实战(模拟主库宕机)
在高可用架构里,最重要的能力就是:主库挂了,业务还能继续跑。
我们来手动测试一下。
1. 主库下线
执行命令,关闭主库(7001):
redis-cli -h 192.168.1.100 -p 7001 -a 1111 shutdown
此时,Sentinel 会立刻发现主库不可用,经过投票仲裁后,将某个从库(如 7003)提升为新的主库,并让其他从库自动跟随它。
2. Spring Boot 日志分析
应用端不需要重启,Lettuce 会自动刷新拓扑。日志里能看到几个关键阶段:
(1) 读写异常触发
应用在 7002 上尝试 GET
时,连接被重置:
(2) 客户端自动重连
Lettuce 马上对新主从发起重连:
同样在 7003 上:
(3) 写请求切换到新主库
不久后,写操作已经走向新的主库(7003):
说明客户端已经从哨兵获取到新的拓扑,写操作不再指向旧主(7001)。
3. 验证结果
- 应用接口在主库宕机期间,短暂会报
Connection reset
; - 很快,Lettuce 自动重连并完成拓扑刷新;
- 读写请求恢复正常,新的主库(7003)继续提供写服务。
整个过程 无需重启应用,Redis 高可用方案真正落地。
六、总结与闭环
本文修复了前两篇文章中的坑:
- 从库和 Sentinel 默认广播是 127.0.0.1,导致应用连接失败
- 修复方式是显式配置
replicaof
为真实IP与sentinel announce-ip
- 并演示了 Spring Boot 如何接入 Redis Sentinel,实现自动主从切换与读写分离
通过最后的 故障切换测试,我们可以清楚看到:即使主库宕机,应用也能在 Sentinel 的帮助下快速恢复,这才是真正的高可用。