Skip to content

四个基础设施包:config 用 viper 加载合并多 yaml;database 管理 GORM 连接池并强制注册审计回调;redis 初始化 go-redis v9 客户端;cache 在 redis 之上提供 group:key 格式缓存助手。启动顺序固定为 config.Load → database.Init → redis.Init → cache 等下游。

关键导出

  • config.Config struct{Server, Datasource, Redis, SAToken, CORS, XSS, ..., SMS, Social}
  • config.Load(paths ...string) 读取并合并 yaml 写包级实例(失败 panic)
  • config.Get() *Config(未 Load panic)
  • 各子配置 ServerConfig / DatasourceConfig / RedisConfig / SATokenConfig / CaptchaConfig / APIEncryptConfig / SocialConfigDefaultXxx() 默认值与 validate()
  • database.New(cfg config.DatasourceConfig) (*gorm.DB, error) / Init() / DB() *gorm.DB / Close(db) / CloseDefault()
  • redis.New(cfg config.RedisConfig) (*goredis.Client, error) / Init() / Client() / Close(client) / SetClient(client) (restore func())
  • cache.Get(ctx, group, key, dest any) (bool, error)(命中/miss/故障三态)
  • cache.Put(ctx, group, key, val, ttl) errorttl=0 不过期)
  • cache.Evict(ctx, group, key) / EvictGroup(ctx, group)(SCAN 分批删,不用 KEYS
  • cache.GetOrSet(ctx, group, key, ttl, dest, load func(ctx)(any,error))(singleflight 合并并发 miss)

典型用法

go
// cmd/standalone/main.go:35
config.Load("configs/application.yaml", "configs/standalone.yaml")
cfg := config.Get().Datasource

// internal/system/service/client_service.go:70
repository.NewClientRepository(database.DB()).SelectPageList(ctx, q, page)

// internal/system/service/config_service.go:71
if hit, _ := cache.Get(ctx, constant.CacheSysConfig, configKey, &cached); hit {
    return cached, nil
}
_ = cache.Put(ctx, constant.CacheSysConfig, configKey, value, constant.CacheTTLSysConfig)
_ = cache.Evict(ctx, constant.CacheSysConfig, b.ConfigKey)

坑/约定

WARNING

  • config.Load 先用 DefaultXxx().setDefaults(v) 注入默认值再读 yaml,缺失字段有兜底;validate() 串联校验所有子配置,任一失败即 panic(启动期 fail-fast)。
  • database GORM 配置 SingularTable:true(表名单数)、SkipDefaultTransaction:trueDisableForeignKeyConstraintWhenMigrating:trueNew 内部 强制repository.RegisterAuditCallbacks(db),任何 main 都无法漏掉;命名策略单数表名,实体无需 TableName()
  • redis.Init 失败 panic;ping 探活失败时也会 client.Close() 回收连接池;SetClient 返回 restore 闭包, 仅供测试注入
  • cache.Get 返回 (bool, error),不能 _ =——miss 与故障语义不同。Redis 故障时 GetOrSetload 仍会被调用(fail-open,错误透传)。序列化统一走 pkg/jsonx(保持 int64 字符串契约)。EvictGroup 用 SCAN+pipeline Del 避免阻塞。 :::

相关页:/architecture/request-flow/getting-started/config/pkg-reference/repository

基于 MIT 协议开源