Redis 哨兵模式:原理、配置与故障排查全解析

Redis 哨兵模式:原理、配置与故障排查全解析

文章目录

  • [Redis 哨兵模式:原理、配置与故障排查全解析](#Redis 哨兵模式:原理、配置与故障排查全解析)
      • 一、哨兵模式的核心定位(通俗理解)
      • 二、哨兵模式的核心组件与架构
        • [1. 核心组件](#1. 核心组件)
        • [2. 典型架构](#2. 典型架构)
      • [三、哨兵模式的核心工作流程(4 步)](#三、哨兵模式的核心工作流程(4 步))
        • [1. 监控(持续检测)](#1. 监控(持续检测))
        • [2. 故障转移(核心步骤)](#2. 故障转移(核心步骤))
        • [3. 通知客户端](#3. 通知客户端)
        • [4. 持续监控(故障恢复后)](#4. 持续监控(故障恢复后))
      • 四、哨兵模式的核心配置(快速上手)
        • [1. 哨兵配置文件(sentinel.conf)](#1. 哨兵配置文件(sentinel.conf))
        • [2. 启动与验证](#2. 启动与验证)
        • [3. 模拟故障转移(测试)](#3. 模拟故障转移(测试))
      • 五、哨兵模式的核心特点
      • [六、哨兵模式 vs Redis Cluster(核心区别)](#六、哨兵模式 vs Redis Cluster(核心区别))
      • [七、哨兵模式常见问题排查(核心故障 + 原因 + 解决方案)](#七、哨兵模式常见问题排查(核心故障 + 原因 + 解决方案))
        • 通用排查前置准备
        • [1、核心问题 1:主节点宕机,哨兵无法触发故障转移(最常见)](#1、核心问题 1:主节点宕机,哨兵无法触发故障转移(最常见))
        • [2、核心问题 2:哨兵误判主节点下线(假死),触发不必要的故障转移](#2、核心问题 2:哨兵误判主节点下线(假死),触发不必要的故障转移)
        • [3、核心问题 3:故障转移完成后,从节点无法同步新主节点](#3、核心问题 3:故障转移完成后,从节点无法同步新主节点)
        • [四、核心问题 4:哨兵节点自身无法加入集群,或与其他哨兵失联](#四、核心问题 4:哨兵节点自身无法加入集群,或与其他哨兵失联)
        • 5、其他高频小问题
          • [问题 1:主节点恢复后,自动成为新主节点的从节点,业务写入地址未更新](#问题 1:主节点恢复后,自动成为新主节点的从节点,业务写入地址未更新)
          • [问题 2:哨兵执行故障转移时,出现「NOGOODSLAVE」错误(日志中可见)](#问题 2:哨兵执行故障转移时,出现「NOGOODSLAVE」错误(日志中可见))
          • [问题 3:主从复制正常,但哨兵显示从节点数为 0](#问题 3:主从复制正常,但哨兵显示从节点数为 0)
        • 6、哨兵模式生产环境避坑指南(预防问题比排查更重要)
      • 总结
      • 总结

Redis 哨兵模式(Redis Sentinel),是官方为解决 主从架构下主节点故障自动恢复 问题而设计的高可用方案 ------ 简单来说,哨兵模式就是给 Redis 主从集群配了一个 "智能监控管家",它能自动监控主从节点的健康状态,主节点宕机时自动把最优的从节点晋升为主节点,还能通知客户端更新连接地址,全程无需人工干预。

一、哨兵模式的核心定位(通俗理解)

主从复制解决了 "数据备份 + 读写分离",但有个致命问题:主节点宕机后,需要人工手动切换从节点为主节点,这会导致服务中断。

而哨兵模式就是主从架构的 "高可用补丁":

  • 哨兵(Sentinel):独立的 Redis 进程(非业务节点),专门监控主从集群;
  • 核心能力:监控→故障判定→自动故障转移→通知客户端,实现主节点故障的 "秒级自动恢复"。

二、哨兵模式的核心组件与架构

1. 核心组件
组件 作用
主节点(Master) 处理写请求,是数据写入源(同主从复制)
从节点(Replica) 同步主节点数据,只读,主节点故障后可被晋升(同主从复制)
哨兵节点(Sentinel) 独立进程,至少部署 3 个(奇数),避免哨兵单点故障
2. 典型架构
plaintext 复制代码
[哨兵节点1] ←→ [哨兵节点2] ←→ [哨兵节点3] (哨兵集群,通过投票机制判定故障)
       ↓          ↓          ↓
[主节点6379] ←→ [从节点6380] ←→ [从节点6381] (主从集群)

哨兵节点之间也会互相通信,同步节点状态,避免 "单个哨兵误判";

哨兵节点不存储业务数据,仅负责监控和故障转移,资源消耗极低。

Redis 哨兵模式架构拓扑图:

这个图表清晰展示哨兵节点、主节点、从节点的部署关系和通信方式,虽然看起来比较乱,但仔细看看还是比较简单的:
Redis Data Nodes
Sentinel Cluster
流言协议/状态同步
流言协议/状态同步
流言协议/状态同步
PING/监控
PING/监控
PING/监控
PING/监控
PING/监控
PING/监控
PING/监控
PING/监控
PING/监控
数据复制
数据复制
查询主节点地址/读写
查询主节点地址/读写
查询主节点地址/读写
业务操作
Sentinel 1

192.168.1.20:26379
Sentinel 2

192.168.1.21:26379
Sentinel 3

192.168.1.22:26379
Master

192.168.1.10:6379

读写
Slave 1

192.168.1.11:6379

只读/复制
Slave 2

192.168.1.12:6379

只读/复制
客户端

Client App

三、哨兵模式的核心工作流程(4 步)

1. 监控(持续检测)

每个哨兵节点会定期(默认 1 秒)向主节点、所有从节点、其他哨兵节点发送PING命令,检测节点是否存活:

若节点在down-after-milliseconds(默认 30 秒)内未回复PONG,哨兵将其标记为 "主观下线(SDOWN)"(单个哨兵的判断);

哨兵节点之间同步这个 "主观下线" 状态,若超过 quorum(配置的法定票数,如 3 个哨兵需 2 票) 的哨兵都判定该主节点下线,就标记为 "客观下线(ODOWN)"(集群共识,避免误判)。

2. 故障转移(核心步骤)

主节点被标记为 "客观下线" 后,哨兵集群会选举出一个 "领头哨兵",由它执行故障转移:

  1. 筛选可用从节点:排除宕机、同步延迟过高、网络不可达的从节点;
  2. 选举最优从节点:按 "优先级(replica-priority)> 复制偏移量(数据同步完整性)> 运行 ID(小的优先)" 排序,选出最优从节点;
  3. 晋升主节点 :领头哨兵向最优从节点发送SLAVEOF NO ONE命令,使其晋升为新主节点;
  4. 重定向其他从节点 :向剩余从节点发送SLAVEOF 新主节点IP 端口命令,让它们同步新主节点的数据;
  5. 标记旧主节点:将宕机的旧主节点标记为 "已下线",若其恢复上线,哨兵会让它成为新主节点的从节点。

Redis 哨兵故障转移流程图:




哨兵集群每秒PING主/从节点
主节点是否响应?
单个哨兵标记主节点「主观下线」
哨兵向集群询问主节点状态
超过半数哨兵确认主节点故障?
取消主观下线,继续监控
标记主节点「客观下线」
哨兵集群投票选举领头哨兵
领头哨兵筛选最优从节点
将最优从节点升级为新主节点
其余从节点切换到新主节点同步数据
通知客户端新主节点地址
原主节点恢复后作为从节点接入新主节点

3. 通知客户端

哨兵会通过 "发布订阅" 机制(频道+switch-master),将新主节点的地址通知给所有连接的客户端,客户端收到后自动更新连接地址,无需重启。

4. 持续监控(故障恢复后)

新主从集群建立后,哨兵继续监控所有节点,重复上述流程,保障高可用。

四、哨兵模式的核心配置(快速上手)

1. 哨兵配置文件(sentinel.conf)
conf 复制代码
# 配置监控的主节点(格式:sentinel monitor 主节点名称 IP 端口 法定票数)
sentinel monitor mymaster 127.0.0.1 6379 2
# 主节点主观下线超时时间(毫秒)
sentinel down-after-milliseconds mymaster 30000
# 故障转移超时时间(毫秒)
sentinel failover-timeout mymaster 180000
# 每次故障转移最多同步的从节点数(避免同时同步压垮新主节点)
sentinel parallel-syncs mymaster 1
# 若主节点有密码,需配置
# sentinel auth-pass mymaster 123456
2. 启动与验证
bash 复制代码
# 1. 先启动主从节点(同主从复制)
redis-server redis-master.conf
redis-server redis-slave1.conf
redis-server redis-slave2.conf

# 2. 启动至少3个哨兵节点(修改端口避免冲突)
redis-sentinel sentinel1.conf  # 默认端口26379
redis-sentinel sentinel2.conf  # 端口26380
redis-sentinel sentinel3.conf  # 端口26381

# 3. 查看哨兵状态(验证监控是否生效)
redis-cli -p 26379
127.0.0.1:26379> INFO sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
mymaster:name=mymaster,status=ok,address=127.0.0.1:6379,slaves=2,sentinels=3
3. 模拟故障转移(测试)
bash 复制代码
# 手动停止主节点(模拟宕机)
redis-cli -p 6379 SHUTDOWN

# 查看哨兵日志/状态,会发现:
# 1. 哨兵判定主节点客观下线;
# 2. 选举最优从节点(如6380)晋升为主节点;
# 3. 原从节点6381同步新主节点6380;
# 4. 哨兵状态中mymaster的address变为127.0.0.1:6380

# 恢复旧主节点(6379),它会自动成为新主节点(6380)的从节点
redis-server redis-master.conf

五、哨兵模式的核心特点

优点 缺点
自动故障转移,无需人工干预 仅解决高可用,未解决数据分片(所有节点存储全量数据,单机容量瓶颈)
哨兵集群部署,无单点故障 故障转移有秒级中断(客户端需适配重连)
轻量级,不影响业务节点性能 配置和运维比纯主从复杂(需管理哨兵集群)
支持通知客户端,无缝切换 仅单主节点,写性能受限于单个节点

六、哨兵模式 vs Redis Cluster(核心区别)

这是新手最易混淆的点,用表格清晰对比:

维度 哨兵模式 Redis Cluster
核心目标 解决主从架构的高可用(自动故障转移) 解决数据分片 + 高可用(分布式集群)
数据存储 所有节点存储全量数据 哈希槽分片,每个主节点存储部分数据
写扩展 仅单主节点,无写扩展能力 多主节点,支持写性能水平扩展
故障转移 仅主节点故障转移 任意主节点故障都能自动转移,且不影响整体
适用场景 数据量小(GB 级)、读多写少、需高可用 数据量大(TB 级)、高并发读写、需水平扩展

七、哨兵模式常见问题排查(核心故障 + 原因 + 解决方案)

哨兵模式的核心故障集中在故障转移失败节点误判上下线从节点无法同步主节点哨兵集群无领头节点四类。

通用排查前置准备

排查前先获取核心状态信息,定位问题方向:

  1. 查看哨兵节点状态:redis-cli -p 哨兵端口 INFO sentinel(确认监控的主节点状态、从节点数、哨兵数)
  2. 查看主从复制状态:redis-cli -p 主/从端口 INFO replication(确认主从角色、同步偏移量、连接状态)
  3. 查看哨兵日志(关键):哨兵启动时指定日志文件,或通过redis-cli -p 哨兵端口 CONFIG GET logfile获取日志路径,日志是排查所有问题的核心依据
  4. 检查节点网络:ping 节点IP+telnet 节点IP 端口(确认主从、哨兵之间网络互通)
1、核心问题 1:主节点宕机,哨兵无法触发故障转移(最常见)
现象

主节点进程挂掉 / 网络中断,但哨兵始终未将从节点晋升为主节点,INFO sentinel中主节点状态仍为okdown但无故障转移动作。

核心原因(按排查优先级排序)
  1. 未达到「客观下线」的法定票数(quorum)
  2. 哨兵集群无法选举出「领头哨兵」
  3. 所有从节点都不可用(宕机 / 同步延迟过高 / 优先级为 0)
  4. 哨兵配置错误(超时时间、密码、端口)
  5. 哨兵节点自身故障(进程挂掉、权限不足)
排查 & 解决步骤

(1) 检查主节点是否被标记为「客观下线(ODOWN)」:

执行redis-cli -p 哨兵端口 SENTINEL master 主节点名称,查看flags字段:

  • 若为S_DOWN(主观下线):说明只有部分哨兵判定主节点下线,未达到 quorum 法定票数
  • 解决方案:确认哨兵集群正常运行的节点数≥quorum(如配置 quorum=2,需至少 2 个哨兵在线并判定主节点下线),重启故障的哨兵节点,确保哨兵之间网络互通。

(2) 检查哨兵是否能选举领头节点

故障转移的前提是哨兵集群选举出唯一的领头哨兵,选举失败则无法执行转移;

失败原因:哨兵节点数为偶数(脑裂风险)、哨兵之间网络不通、哨兵配置的master-name不一致;

解决方案:哨兵节点数必须部署奇数个(≥3) ,检查所有哨兵的master-name配置一致,确保哨兵之间 26379(默认)端口互通。

(3) 检查从节点可用性(哨兵筛选从节点的规则)

哨兵会过滤掉以下从节点,若全部被过滤则无法转移:

从节点状态为宕机:INFO replicationslave0stateonline

从节点优先级为 0:redis-cli -p 从节点端口 CONFIG GET replica-priority返回 0(优先级 0 表示永不被晋升);

同步延迟过高:从节点的master_repl_offset(同步偏移量)与主节点差值过大,超过哨兵判定的有效范围;

从节点连接主节点时长过短:刚连接的从节点未完成全量同步,被哨兵判定为 "未就绪";

解决方案:重启故障从节点、将有效从节点的replica-priority改为 1-100(默认 100,值越小优先级越高)、等待从节点完成全量同步后再触发故障转移。

(4) 检查哨兵核心配置

确认down-after-milliseconds(主观下线超时)配置一致:所有哨兵对同一主节点的该配置必须相同,否则会出现判定不一致;

确认auth-pass配置正确:若主节点设置了密码,所有哨兵必须配置sentinel auth-pass 主节点名称 密码,否则哨兵无法连接主节点,无法判定状态;

确认parallel-syncs(故障转移后从节点同步新主节点的数量):若配置过大,可能导致新主节点被压垮,但不会直接导致转移失败。

2、核心问题 2:哨兵误判主节点下线(假死),触发不必要的故障转移
现象

主节点实际正常运行(能处理请求),但哨兵将其标记为下线并触发故障转移,导致主节点切换,业务出现短暂抖动。

核心原因
  1. 主节点压力过高,导致 PING 响应超时
  2. 主观下线超时时间(down-after-milliseconds)配置过小
  3. 主节点与哨兵之间网络抖动(丢包、延迟高)
  4. 主节点开启了保护模式,拒绝哨兵的 PING 请求
排查 & 解决步骤

(1) 调大主观下线超时时间

生产环境不建议将 down-after-milliseconds 设置小于 30000ms(30 秒),默认 30 秒是合理值,若网络环境较差,可调至 60000ms;

命令:redis-cli -p 哨兵端口 SENTINEL set 主节点名称 down-after-milliseconds 60000(所有哨兵需统一修改)。

(2) 排查主节点高负载原因

主节点 CPU / 内存 / 磁盘 IO 过高,会导致无法及时响应哨兵的 PING 命令;

排查:redis-cli -p 主节点端口 INFO stats(查看命令执行量)、top(查看 Redis 进程 CPU 占用)、iotop(查看磁盘 IO);

解决方案:优化慢查询(SLOWLOG get)、限制大 key 操作、扩容主节点资源、通过从节点分担读请求。

(3) 解决网络抖动问题

主节点与哨兵部署在不同机房 / 网段时,易出现网络丢包;

排查:ping 主节点IP -i 0.1(持续 ping,查看丢包率)、mtr 主节点IP(查看网络路由延迟);

解决方案:将哨兵与主从节点部署在同一网段,优化网络链路,避免跨公网部署哨兵。

(4) 关闭主节点的保护模式

若主节点开启了保护模式(protected-mode yes),且未配置绑定 IP,会拒绝哨兵的远程连接;

解决方案:redis-cli -p 主节点端口 CONFIG SET protected-mode no(生产环境建议配合bind配置指定哨兵 IP,更安全)。

3、核心问题 3:故障转移完成后,从节点无法同步新主节点
现象

哨兵将从节点 A 晋升为新主节点,但其他从节点无法同步新主节点 A,INFO replication中从节点的stateconnectingerror

核心原因
  1. 新主节点设置了密码,从节点未配置 masterauth
  2. 新主节点的 replica-read-only 配置被修改(非只读)
  3. 从节点与新主节点网络不通,或端口被防火墙拦截
  4. 新主节点的复制积压缓冲区满,导致从节点无法做部分复制,全量复制又失败
排查 & 解决步骤

(1) 检查新主节点密码与从节点 masterauth 配置

若新主节点有密码:redis-cli -p 新主节点端口 CONFIG GET requirepass

从节点必须配置相同密码:redis-cli -p 从节点端口 CONFIG SET masterauth 密码,并持久化配置(CONFIG REWRITE)。

(2) 确认新主节点为只读模式(故障转移后自动设置,若被修改会出问题)

新主节点晋升后,哨兵会自动将其设为replica-read-only no(可写),但从节点必须保持replica-read-only yes

检查从节点配置:redis-cli -p 从节点端口 CONFIG GET replica-read-only,确保值为yes

(3) 检查从节点与新主节点的网络连通性

从节点执行telnet 新主节点IP 新主节点端口,确认端口可通;

关闭防火墙 / 安全组中拦截 Redis 端口的规则(生产环境建议仅开放主从、哨兵之间的端口)。

(4) 扩大新主节点的复制积压缓冲区

复制积压缓冲区过小,会导致从节点断线重连后无法做部分复制,触发全量复制时若 RDB 文件过大易失败;

调整配置:redis-cli -p 新主节点端口 CONFIG SET repl-backlog-size 1gb(根据业务量调整,默认 1MB),repl-backlog-ttl 86400(缓冲区过期时间)。

四、核心问题 4:哨兵节点自身无法加入集群,或与其他哨兵失联
现象

启动新哨兵节点后,INFO sentinelsentinels数量未增加;或部分哨兵节点无法获取其他哨兵的状态,导致投票失败。

核心原因
  1. 哨兵的master-namemaster-ipmaster-port配置与其他哨兵不一致
  2. 哨兵之间的 26379(默认)端口未互通,防火墙拦截
  3. 哨兵节点的daemonize yes配置后,日志 /pid 文件权限不足,导致进程假死
  4. Redis 版本不一致(哨兵与主从、哨兵之间版本差异过大)
排查 & 解决步骤

(1) 统一所有哨兵的核心配置

所有哨兵对同一主节点的master-namedown-after-millisecondsquorum必须完全一致,否则无法加入同一哨兵集群;

示例:所有哨兵都配置sentinel monitor mymaster 127.0.0.1 6379 2

(2) 开放哨兵之间的通信端口

哨兵默认使用 26379 端口互相通信,需确保所有哨兵节点之间该端口可通;

临时关闭防火墙:systemctl stop firewalld(生产环境建议通过firewall-cmd开放指定端口)。

(3) 检查哨兵进程的文件权限

若哨兵配置了logfilepidfile,需确保 Redis 用户有读写权限,否则进程启动后会立即退出;

示例:chown -R redis:redis /var/log/redis/ /var/run/redis/

(4) 保证所有节点的 Redis 版本一致

生产环境建议哨兵、主节点、从节点使用同一稳定版本(如 6.2.8、7.0.12),避免版本差异导致的协议不兼容;

禁止混合使用低版本(如 3.2)和高版本(如 7.0)哨兵,会出现状态同步失败。

5、其他高频小问题
问题 1:主节点恢复后,自动成为新主节点的从节点,业务写入地址未更新

原因:客户端未适配哨兵的发布订阅机制 ,未监听+switch-master频道,导致不知道主节点地址变化;

解决方案:客户端使用支持哨兵自动发现的 Redis 客户端(如 Java 的 Jedis、Spring Data Redis),配置哨兵地址而非固定主节点地址。

问题 2:哨兵执行故障转移时,出现「NOGOODSLAVE」错误(日志中可见)

原因:所有从节点都被哨兵判定为 "不可用"(如优先级 0、同步延迟过高、宕机);

解决方案:参考「核心问题 1」的步骤 3,修复从节点的可用性。

问题 3:主从复制正常,但哨兵显示从节点数为 0

原因:哨兵连接主节点失败(如密码错误、网络不通),无法获取从节点信息;

解决方案:检查哨兵的auth-pass配置,确保哨兵能正常连接主节点(redis-cli -p 哨兵端口 SENTINEL ping返回PONG)。

6、哨兵模式生产环境避坑指南(预防问题比排查更重要)
  1. 部署规范 :哨兵节点数必须为奇数(3/5 个),与主从节点分开部署(避免主节点宕机导致哨兵同时宕机),同一机房部署即可,无需跨机房。
  2. 配置规范 :所有哨兵的master-namedown-after-millisecondsquorum完全一致down-after-milliseconds建议≥30000ms,quorum设置为「哨兵节点数 / 2 +1」(如 3 个哨兵设为 2)。
  3. 权限规范:Redis 进程使用普通用户(如 redis)运行,日志 /pid/ 数据目录配置独立权限,避免权限不足导致进程假死。
  4. 网络规范 :仅开放主从、哨兵之间的 Redis 端口(6379/26379),禁止公网直接访问,配置bind指定允许连接的 IP。
  5. 客户端规范 :禁止客户端直接配置主节点 IP,必须通过哨兵地址获取主节点,适配+switch-master事件的自动重连。
  6. 监控规范 :监控哨兵的INFO sentinel状态、主从节点的replication状态,监控日志中的「ODOWN」「FAILOVER」关键词,及时告警。
  7. 版本规范:统一 Redis 所有节点的版本,使用官方稳定版,避免使用测试版 / 开发版。

总结

  1. 哨兵模式是主从架构的高可用增强版,核心解决 "主节点宕机自动切换",但未解决数据分片和写扩展问题;
  2. 哨兵集群需部署奇数个(≥3),通过 "主观下线→客观下线→领头选举→故障转移" 实现自动化;
    / 数据目录配置独立权限,避免权限不足导致进程假死。
  3. 网络规范 :仅开放主从、哨兵之间的 Redis 端口(6379/26379),禁止公网直接访问,配置bind指定允许连接的 IP。
  4. 客户端规范 :禁止客户端直接配置主节点 IP,必须通过哨兵地址获取主节点,适配+switch-master事件的自动重连。
  5. 监控规范 :监控哨兵的INFO sentinel状态、主从节点的replication状态,监控日志中的「ODOWN」「FAILOVER」关键词,及时告警。
  6. 版本规范:统一 Redis 所有节点的版本,使用官方稳定版,避免使用测试版 / 开发版。

总结

  1. 哨兵模式是主从架构的高可用增强版,核心解决 "主节点宕机自动切换",但未解决数据分片和写扩展问题;
  2. 哨兵集群需部署奇数个(≥3),通过 "主观下线→客观下线→领头选举→故障转移" 实现自动化;
  3. 哨兵模式适合中小规模 Redis 场景(数据量 GB 级),大规模分布式场景建议用 Redis Cluster。
相关推荐
六义义3 小时前
java基础十二
java·数据结构·算法
ʚB҉L҉A҉C҉K҉.҉基҉德҉^҉大3 小时前
自动化机器学习(AutoML)库TPOT使用指南
jvm·数据库·python
哈__3 小时前
多模融合 一体替代:金仓数据库 KingbaseES 重构企业级统一数据基座
数据库·重构
老邓计算机毕设3 小时前
SSM医院病人信息管理系统e7f6b(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·医院信息化·ssm 框架·病人信息管理
一叶星殇3 小时前
.NET WebAPI:用 Nginx 还是 IIS 更好
运维·nginx·.net
毕设源码-钟学长3 小时前
【开题答辩全过程】以 基于SpringBoot的智能书城推荐系统的设计与实现为例,包含答辩的问题和答案
java·spring boot·后端
2601_949613023 小时前
flutter_for_openharmony家庭药箱管理app实战+药品分类实现
大数据·数据库·flutter
笨手笨脚の4 小时前
深入理解 Java 虚拟机-03 垃圾收集
java·jvm·垃圾回收·标记清除·标记复制·标记整理
莫问前路漫漫4 小时前
WinMerge v2.16.41 中文绿色版深度解析:文件对比与合并的全能工具
java·开发语言·python·jdk·ai编程
九皇叔叔4 小时前
【03】SpringBoot3 MybatisPlus BaseMapper 源码分析
java·开发语言·mybatis·mybatis plus