package app import ( "fmt" "log" "sync" "github.com/fsnotify/fsnotify" "github.com/spf13/viper" ) // DBConfig 数据库单个配置结构 type DBConfig struct { Host string Port int Username string Password string Dbname string } // dbConfigs 全局变量,存放所有数据库配置,key为配置名,如 test1, test2 var ( dbConfigs map[string]DBConfig mu sync.RWMutex v *viper.Viper ) // InitDBConfig 初始化并加载 db.yaml 配置,同时启动监听 func InitDBConfig(configPath string) error { v = viper.New() v.SetConfigFile(configPath) v.SetConfigType("yaml") if err := v.ReadInConfig(); err != nil { return fmt.Errorf("读取数据库配置失败: %w", err) } if err := unmarshalConfigs(); err != nil { return err } // 监听配置文件变化 v.WatchConfig() v.OnConfigChange(func(e fsnotify.Event) { log.Printf("数据库配置文件发生变化: %s\n", e.Name) if err := unmarshalConfigs(); err != nil { log.Printf("重新加载数据库配置失败: %v\n", err) } else { log.Println("数据库配置已更新") } }) return nil } // unmarshalConfigs 解析配置到全局变量,内部加锁保证并发安全 func unmarshalConfigs() error { mu.Lock() defer mu.Unlock() temp := make(map[string]DBConfig) if err := v.Unmarshal(&temp); err != nil { return fmt.Errorf("解析数据库配置失败: %w", err) } dbConfigs = temp return nil } // GetDBConfigs 并发安全地返回当前的所有数据库配置副本 func GetDBConfigs() map[string]DBConfig { mu.RLock() defer mu.RUnlock() // 返回一份拷贝,避免外部修改内部数据 res := make(map[string]DBConfig, len(dbConfigs)) for k, v := range dbConfigs { res[k] = v } return res }