Files
backend/internal/config/database.go
lan f63c795dcb
All checks were successful
Build Backend / build (push) Successful in 2m1s
Build Backend / build-docker (push) Successful in 1m26s
feat(db): implement read-write splitting for postgres
Add support for database read replicas using the GORM dbresolver plugin. This allows for scaling read operations by distributing them across one or multiple replica nodes.

- Update `DatabaseConfig` to support single and multiple replica configurations.
- Add configuration options for replica connection pooling and selection policy.
- Integrate `dbresolver` in the database initialization process for PostgreSQL.
- Add helper methods to aggregate replica configurations.
2026-05-15 14:44:40 +08:00

61 lines
2.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package config
import "fmt"
// DatabaseConfig 数据库配置
type DatabaseConfig struct {
Type string `mapstructure:"type"`
SQLite SQLiteConfig `mapstructure:"sqlite"`
Postgres PostgresConfig `mapstructure:"postgres"`
MaxIdleConns int `mapstructure:"max_idle_conns"`
MaxOpenConns int `mapstructure:"max_open_conns"`
LogLevel string `mapstructure:"log_level"`
SlowThresholdMs int `mapstructure:"slow_threshold_ms"`
IgnoreRecordNotFound bool `mapstructure:"ignore_record_not_found"`
ParameterizedQueries bool `mapstructure:"parameterized_queries"`
// 读写分离:单副本配置(支持环境变量,如 APP_DATABASE_REPLICA_HOST
Replica PostgresConfig `mapstructure:"replica"`
// 读写分离:多副本配置(仅 YAML 支持,环境变量无法覆盖切片结构体)
Replicas []PostgresConfig `mapstructure:"replicas"`
ReplicaPolicy string `mapstructure:"replica_policy"`
ReplicaMaxIdle int `mapstructure:"replica_max_idle_conns"`
ReplicaMaxOpen int `mapstructure:"replica_max_open_conns"`
}
// SQLiteConfig SQLite 配置
type SQLiteConfig struct {
Path string `mapstructure:"path"`
}
// PostgresConfig PostgreSQL 配置(主库和副本共用)
type PostgresConfig struct {
Host string `mapstructure:"host"`
Port int `mapstructure:"port"`
User string `mapstructure:"user"`
Password string `mapstructure:"password"`
DBName string `mapstructure:"dbname"`
SSLMode string `mapstructure:"sslmode"`
}
// DSN 返回 PostgreSQL 连接字符串
func (d PostgresConfig) DSN() string {
return fmt.Sprintf(
"host=%s port=%d user=%s password=%s dbname=%s sslmode=%s",
d.Host, d.Port, d.User, d.Password, d.DBName, d.SSLMode,
)
}
// HasReplica 返回是否配置了读副本(单副本或多副本)
func (d DatabaseConfig) HasReplica() bool {
return d.Replica.Host != "" || len(d.Replicas) > 0
}
// AllReplicas 返回所有读副本配置(合并单副本 + 多副本)
func (d DatabaseConfig) AllReplicas() []PostgresConfig {
var result []PostgresConfig
if d.Replica.Host != "" {
result = append(result, d.Replica)
}
result = append(result, d.Replicas...)
return result
}