高级主题
DBResolver
登录后可跨设备保存划线和私人笔记登录
DBResolver 为 GORM 添加了多数据库支持,支持以下功能:
- 多个主库与从库
- 读写分离
- 根据当前操作的表/结构体自动切换连接
- 手动切换连接
- 主库/从库负载均衡
- 支持 RAW SQL
- 支持事务
https://github.com/go-gorm/dbresolver
使用方式
import (
"gorm.io/gorm"
"gorm.io/plugin/dbresolver"
"gorm.io/driver/mysql"
)
db, err := gorm.Open(mysql.Open("db1_dsn"), &gorm.Config{})
db.Use(dbresolver.Register(dbresolver.Config{
Sources: []gorm.Dialector{mysql.Open("db2_dsn")},
Replicas: []gorm.Dialector{mysql.Open("db3_dsn"), mysql.Open("db4_dsn")},
Policy: dbresolver.RandomPolicy{},
TraceResolverMode: true,
}).Register(dbresolver.Config{
Replicas: []gorm.Dialector{mysql.Open("db5_dsn")},
}, &User{}, &Address{}).Register(dbresolver.Config{
Sources: []gorm.Dialector{mysql.Open("db6_dsn"), mysql.Open("db7_dsn")},
Replicas: []gorm.Dialector{mysql.Open("db8_dsn")},
}, "orders", &Product{}, "secondary"))自动切换连接
DBResolver 会根据当前操作的表/结构体自动切换连接。
对于 RAW SQL,DBResolver 会从 SQL 中提取表名来匹配 resolver,并且除非 SQL 以 SELECT 开头(SELECT... FOR UPDATE 除外),否则会使用 sources,例如:
db.Table("users").Rows()
db.Model(&User{}).Find(&AdvancedUser{})
db.Exec("update users set name = ?", "jinzhu")
db.Raw("select name from users").Row().Scan(&name)
db.Create(&user)
db.Delete(&User{}, "name = ?", "jinzhu")
db.Table("users").Update("name", "jinzhu")
db.Find(&Pet{})
db.Save(&Pet{})
db.Find(&Order{})
db.Table("orders").Find(&Report{}) 读写分离
DBResolver 基于当前使用的 GORM 回调 实现读写分离。
对于 Query、Row 回调,除非指定了 Write 模式,否则将使用 replicas
对于 Raw 回调,语句被视为只读,如果 SQL 以 SELECT 开头则将使用 replicas
手动切换连接
db.Clauses(dbresolver.Write).First(&user)
db.Clauses(dbresolver.Use("secondary")).First(&user)
db.Clauses(dbresolver.Use("secondary"), dbresolver.Write).First(&user)事务
使用事务时,DBResolver 将持续使用当前事务,不会根据配置切换到主库/从库
但你可以在开始事务之前指定使用哪个数据库,例如:
tx := db.Clauses(dbresolver.Read).Begin()
tx := db.Clauses(dbresolver.Write).Begin()
tx := db.Clauses(dbresolver.Use("secondary"), dbresolver.Write).Begin()负载均衡
GORM 支持基于策略对主库/从库进行负载均衡,策略应为实现以下接口的结构体:
type Policy interface {
Resolve([]gorm.ConnPool) gorm.ConnPool
}目前仅实现了 RandomPolicy,如果未指定其他策略,它将是默认选项。
连接池
db.Use(
dbresolver.Register(dbresolver.Config{ }).
SetConnMaxIdleTime(time.Hour).
SetConnMaxLifetime(24 * time.Hour).
SetMaxIdleConns(100).
SetMaxOpenConns(200)
)评论
登录后参与评论
正在加载评论…
KnowForge