必须显式注册dbresolver插件且顺序正确,gorm.open后立即调用db.use(dbresolver.register()),否则读写分离不生效,所有操作默认走主库;主从dsn须分离配置,从库需read_only=on,连接池须独立调优。

直接用 gorm.Open 初始化一个 DB 实例,不注册 dbresolver 插件,读写分离就完全不生效——所有操作默认走主库,或因从库配置失败而静默 fallback,线上压测时主库 CPU 突然飙高,往往就是这个原因。
必须显式注册 dbresolver 插件,且顺序不能错
dbresolver.Register() 不是可选插件,是读写分离的开关。它必须在 gorm.Open 成功返回 *gorm.DB 后立刻调用,不能前置,也不能漏掉。
-
gorm.Open只负责初始化基础连接(通常只传主库 DSN),此时还无路由能力 - 紧接着必须执行
db.Use(dbresolver.Register()),否则Sources和Replicas配置不会加载 - 如果注册前就调用了
db.AddSlave(),GORM 会忽略该从库,后续读请求仍打主库 - 检查
dbresolver.Register()的返回 error —— 它不 panic,但失败即等于没启用
主库和从库 DSN 必须分开传,不能拼接
GORM 不支持类似 user:pass@tcp(192.168.1.1:3306,192.168.1.2:3306)/db 这种多地址写法,驱动会报 invalid connection 或静默降级。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 主库 DSN 单独传给
gorm.Open,作为基础实例的连接源 - 每个从库 DSN 必须调用
db.AddSlave(dsn)显式注册,且要检查返回的error - 从库 DSN 中必须确保 MySQL 层已开启
read_only=ON,否则SELECT FOR UPDATE会触发ERROR 1290 - 若某从库地址不可达,
AddSlave返回 error 被忽略,该从库不会加入负载池,但日志无提示,需靠db.Debug().Find()观察实际 IP
方法语义决定路由,不是 SQL 文本
GORM 不解析 SQL 字符串,Raw("SELECT * FROM users") 默认走从库,但 Raw("INSERT INTO ...") 就会直接报错: ERROR: cannot execute INSERT in a read-only transaction。
- 写操作:
Create、Save、Update、Delete、Transaction强制走Sources(主库) - 读操作:
Find、First、Take、Count、Scan默认走Replicas(从库),前提是至少一个从库注册成功且健康 - 事务内所有操作(包括
tx.Find())强制绑定开启事务的主库连接,无法中途切到从库 - 强一致读(如刚
Create完立刻First)必须显式加db.Session(&gorm.Session{Write: true})或db.Clauses(dbresolver.Write)
连接池和健康检查必须独立配置
主库和从库是两种负载特征完全不同的服务端点:主库写多、延迟敏感;从库读多、可容忍延迟。共用 SetMaxOpenConns 或跳过 Ping() 校验,上线后必出问题。
- 主库建议:
masterDB.SetMaxOpenConns(20)、SetWriteTimeout(2 * time.Second)、初始化后立即masterDB.Ping(),失败直接 panic - 从库建议:
slaveDB.SetMaxOpenConns(100)、SetReadTimeout(8 * time.Second)、SetConnMaxLifetime(15 * time.Minute) - 每个从库注册后应异步做一次
Ping(),超时则标记为不可用,避免请求持续发往宕机节点 -
dbresolver不自动剔除故障从库,也无延迟感知能力——Seconds_Behind_Master得业务层自己轮询、过滤、调用Resolver.ReplaceReplicas()刷新
最常被忽略的一点:事务函数里不小心调了封装好的 ReadDB().First(),等于开了两个独立数据库会话,刚写入的数据在从库查不到,业务逻辑直接错乱。路由意图必须由上下文或显式 Clause 控制,不能靠“看起来像读”来猜测。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










