You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
79 lines
2.7 KiB
79 lines
2.7 KiB
package config
|
|
|
|
import (
|
|
"github.com/google/uuid"
|
|
"github.com/spf13/viper"
|
|
"log"
|
|
"strings"
|
|
)
|
|
|
|
// Config 结构体必须与 config.yml 的结构完全对应
|
|
// 使用 `mapstructure` tag 来帮助 Viper 正确映射 YAML 键名到 Go 结构体字段
|
|
type Config struct {
|
|
Server ServerConfig `mapstructure:"server"`
|
|
Auth AuthConfig `mapstructure:"auth"`
|
|
Redis RedisConfig `mapstructure:"redis"`
|
|
}
|
|
|
|
type ServerConfig struct {
|
|
AppListenPort string `mapstructure:"app_listen_port"`
|
|
DeviceListenPort string `mapstructure:"device_listen_port"`
|
|
|
|
// [新增]
|
|
InstanceID string `mapstructure:"instance_id"`
|
|
GrpcListenAddr string `mapstructure:"grpc_listen_addr"`
|
|
GrpcAdvertiseAddr string `mapstructure:"grpc_advertise_addr"`
|
|
}
|
|
|
|
type AuthConfig struct {
|
|
AppAccessSecret string `mapstructure:"app_access_secret"`
|
|
DeviceRelaySecret string `mapstructure:"device_relay_secret"`
|
|
}
|
|
|
|
type RedisConfig struct {
|
|
Enabled bool `mapstructure:"enabled"`
|
|
Addr string `mapstructure:"addr"`
|
|
Password string `mapstructure:"password"`
|
|
DB int `mapstructure:"db"`
|
|
SessionTTLSeconds int `mapstructure:"session_ttl_seconds"` // 确保有这个字段
|
|
|
|
// [新增]
|
|
InstanceRegistryKey string `mapstructure:"instance_registry_key"`
|
|
InstanceTTLSeconds int `mapstructure:"instance_ttl_seconds"`
|
|
}
|
|
|
|
// Cfg 是一个全局变量,用于在项目的任何地方访问配置
|
|
var Cfg *Config
|
|
|
|
// LoadConfig 是初始化函数,负责读取和解析配置文件
|
|
func LoadConfig() {
|
|
viper.SetConfigName("config") // 配置文件名 (不带扩展名)
|
|
viper.SetConfigType("yml") // 配置文件类型
|
|
viper.AddConfigPath(".") // 在当前工作目录查找配置文件
|
|
viper.AddConfigPath("./config") // 也在 config 目录查找
|
|
|
|
// [关键] 开启环境变量支持
|
|
// 这允许你通过环境变量覆盖配置文件中的值
|
|
// 例如:SERVER_APP_LISTEN_ADDR=":9000" 会覆盖文件中的设置
|
|
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
|
viper.AutomaticEnv()
|
|
|
|
// 读取配置文件
|
|
if err := viper.ReadInConfig(); err != nil {
|
|
// 如果配置文件没找到,也没关系,可能完全通过环境变量配置
|
|
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
|
|
log.Fatalf("Fatal error reading config file: %v", err)
|
|
}
|
|
}
|
|
|
|
// 将读取到的配置反序列化到 Cfg 结构体中
|
|
if err := viper.Unmarshal(&Cfg); err != nil {
|
|
log.Fatalf("Unable to decode config into struct: %v", err)
|
|
}
|
|
|
|
// [新增] 如果 instance_id 未配置,则自动生成
|
|
if Cfg.Server.InstanceID == "" {
|
|
Cfg.Server.InstanceID = uuid.New().String()
|
|
}
|
|
log.Printf("Configuration loaded. Server Instance ID: %s", Cfg.Server.InstanceID)
|
|
}
|
|
|