diff --git a/config-dev.yaml b/config-dev.yaml new file mode 100644 index 0000000..2cde784 --- /dev/null +++ b/config-dev.yaml @@ -0,0 +1,9 @@ +mysql: + host: 127.0.0.1 + password: root + port: 3306 + user: root +redis: + host: 127.0.0.1 + password: sundynix + port: 6379 diff --git a/config-prod.yaml b/config-prod.yaml new file mode 100644 index 0000000..3102034 --- /dev/null +++ b/config-prod.yaml @@ -0,0 +1,9 @@ +mysql: + host: 192.168.100.127 + password: root + port: 3306 + user: root +redis: + host: 192.168.100.127 + password: sundynix + port: 6379 diff --git a/config.yaml b/config.yaml deleted file mode 100644 index b1599f6..0000000 --- a/config.yaml +++ /dev/null @@ -1,9 +0,0 @@ -db: - host: 127.0.0.1 - port: 3306 - user: root - password: root - -redis: - host: 127.0.0.1 - port: 6379 \ No newline at end of file diff --git a/config/config.go b/config/config.go index 6a8f828..23a026f 100644 --- a/config/config.go +++ b/config/config.go @@ -1,5 +1,6 @@ package config -type Config struct { - DB DB `mapstructure:"db" json:"db" yaml:"db"` +type Server struct { + Mysql Mysql `mapstructure:"mysql" json:"mysql" yaml:"mysql"` + Redis Redis `mapstructure:"redis" json:"redis" yaml:"redis"` } diff --git a/config/config_redis.go b/config/config_redis.go new file mode 100644 index 0000000..6649685 --- /dev/null +++ b/config/config_redis.go @@ -0,0 +1,7 @@ +package config + +type Redis struct { + Host string `mapstructure:"host" json:"host" yaml:"host"` + Port int `mapstructure:"port" json:"port" yaml:"port"` + Password string `mapstructure:"password" json:"password" yaml:"password"` +} diff --git a/config/gorm_mysql.go b/config/gorm_mysql.go new file mode 100644 index 0000000..601cf41 --- /dev/null +++ b/config/gorm_mysql.go @@ -0,0 +1,21 @@ +package config + +type Mysql struct { + Prefix string `mapstructure:"prefix" json:"prefix" yaml:"prefix"` // 数据库前缀 + Port string `mapstructure:"port" json:"port" yaml:"port"` // 数据库端口 + Config string `mapstructure:"config" json:"config" yaml:"config"` // 高级配置 + Dbname string `mapstructure:"db-name" json:"db-name" yaml:"db-name"` // 数据库名 + User string `mapstructure:"user" json:"user" yaml:"user"` // 数据库账号 + Password string `mapstructure:"password" json:"password" yaml:"password"` // 数据库密码 + Host string `mapstructure:"host" json:"host" yaml:"host"` // 数据库地址 + Engine string `mapstructure:"engine" json:"engine" yaml:"engine" default:"InnoDB"` // 数据库引擎,默认InnoDB + LogMode string `mapstructure:"log-mode" json:"log-mode" yaml:"log-mode"` // 是否开启Gorm全局日志 + MaxIdleConns int `mapstructure:"max-idle-conns" json:"max-idle-conns" yaml:"max-idle-conns"` // 空闲中的最大连接数 + MaxOpenConns int `mapstructure:"max-open-conns" json:"max-open-conns" yaml:"max-open-conns"` // 打开到数据库的最大连接数 + Singular bool `mapstructure:"singular" json:"singular" yaml:"singular"` // 是否开启全局禁用复数,true表示开启 + LogZap bool `mapstructure:"log-zap" json:"log-zap" yaml:"log-zap"` // 是否通过zap写入日志文件 +} + +func (m *Mysql) Dsn() string { + return m.User + ":" + m.Password + "@tcp(" + m.Host + ":" + m.Port + ")/" + m.Dbname + "?" + m.Config +} diff --git a/config/gorm_pgsql.go b/config/gorm_pgsql.go new file mode 100644 index 0000000..8767cd0 --- /dev/null +++ b/config/gorm_pgsql.go @@ -0,0 +1,29 @@ +package config + +type Pgsql struct { + Prefix string `mapstructure:"prefix" json:"prefix" yaml:"prefix"` // 数据库前缀 + Port string `mapstructure:"port" json:"port" yaml:"port"` // 数据库端口 + Config string `mapstructure:"config" json:"config" yaml:"config"` // 高级配置 + Dbname string `mapstructure:"db-name" json:"db-name" yaml:"db-name"` // 数据库名 + User string `mapstructure:"user" json:"user" yaml:"user"` // 数据库账号 + Password string `mapstructure:"password" json:"password" yaml:"password"` // 数据库密码 + Path string `mapstructure:"path" json:"path" yaml:"path"` // 数据库地址 + Engine string `mapstructure:"engine" json:"engine" yaml:"engine" default:"InnoDB"` // 数据库引擎,默认InnoDB + LogMode string `mapstructure:"log-mode" json:"log-mode" yaml:"log-mode"` // 是否开启Gorm全局日志 + MaxIdleConns int `mapstructure:"max-idle-conns" json:"max-idle-conns" yaml:"max-idle-conns"` // 空闲中的最大连接数 + MaxOpenConns int `mapstructure:"max-open-conns" json:"max-open-conns" yaml:"max-open-conns"` // 打开到数据库的最大连接数 + Singular bool `mapstructure:"singular" json:"singular" yaml:"singular"` // 是否开启全局禁用复数,true表示开启 + LogZap bool `mapstructure:"log-zap" json:"log-zap" yaml:"log-zap"` // 是否通过zap写入日志文件 +} + +// Dsn 基于配置文件获取 dsn +// Author [SliverHorn](https://github.com/SliverHorn) +func (p *Pgsql) Dsn() string { + return "host=" + p.Path + " user=" + p.User + " password=" + p.Password + " dbname=" + p.Dbname + " port=" + p.Port + " " + p.Config +} + +// LinkDsn 根据 dbname 生成 dsn +// Author [SliverHorn](https://github.com/SliverHorn) +func (p *Pgsql) LinkDsn(dbname string) string { + return "host=" + p.Path + " user=" + p.User + " password=" + p.Password + " dbname=" + dbname + " port=" + p.Port + " " + p.Config +} diff --git a/core/internal/constant.go b/core/internal/constant.go new file mode 100644 index 0000000..a1e84e6 --- /dev/null +++ b/core/internal/constant.go @@ -0,0 +1,8 @@ +package internal + +const ( + ConfigDefaultFile = "config-dev.yaml" + ConfigProdFile = "config-prod.yaml" + ConfigDebugFile = "config-debug.yaml" + ConfigReleaseFile = "config-release.yaml" +) diff --git a/core/viper.go b/core/viper.go index 97f6b88..a361cf2 100644 --- a/core/viper.go +++ b/core/viper.go @@ -1,32 +1,60 @@ package core import ( + "flag" "fmt" + "github.com/fsnotify/fsnotify" "github.com/spf13/viper" - "sundynix-go/config" + "os" + "sundynix-go/core/internal" + "sundynix-go/global" ) -func Viper() (cfg *config.Config) { - viper.SetConfigFile("config.yaml") - viper.SetConfigType("yaml") - viper.AddConfigPath("../") +func Viper() *viper.Viper { + config := getConfigPath() + fmt.Println("配置文件路径:", config) + v := viper.New() + v.AddConfigPath("../../config-dev.yaml") + v.SetConfigFile(config) + v.SetConfigType("yaml") - if err := viper.ReadInConfig(); err != nil { - if _, ok := err.(viper.ConfigFileNotFoundError); ok { - // Config file not found; ignore error if desired - fmt.Println("Config file not found") - } else { - // Config file was found but another error was produced - fmt.Println("Read config file error ") - } + err := v.ReadInConfig() + if err != nil { + panic(fmt.Errorf("fatal error config file: %w", err)) } - //将所有值或特定值解组到结构、映射中 - //反序列化所有配置项 - if err := viper.Unmarshal(&cfg); err != nil { - fmt.Printf("unmarshal error %s", err) + //监听配置文件变化并热加载 + v.WatchConfig() + + //监听配置文件变化事件 + v.OnConfigChange(func(e fsnotify.Event) { + fmt.Println("config file changed:", e.Name) + if err = v.Unmarshal(&global.Config); err != nil { + fmt.Println(err) + } + }) + + //将读取的配置信息反序列化到全局变量Conf中 + if err = v.Unmarshal(&global.Config); err != nil { + panic(fmt.Errorf("fatal error unmarshal config: %w", err)) + } + return v +} + +// 获取配置文件路径 优先级: 命令行 > 环境变量 > 默认值 +func getConfigPath() (config string) { + flag.StringVar(&config, "c", "", "choose config file") + flag.Parse() + + // 命令行参数不为空 将值赋值于config + if config != "" { + fmt.Printf("正在使用命令行的 '-c' 参数传递的值, config 的路径为 %s\n", config) return } + _, err := os.Stat(config) + if err != nil || os.IsNotExist(err) { + config = internal.ConfigDefaultFile + fmt.Printf("配置文件路径不存在, 使用默认配置文件路径: %s\n", config) + } return - } diff --git a/global/global.go b/global/global.go new file mode 100644 index 0000000..93c99ac --- /dev/null +++ b/global/global.go @@ -0,0 +1,12 @@ +package global + +import ( + "github.com/spf13/viper" + "sundynix-go/config" +) + +// 全局变量 加载在内存中 +var ( + Viper *viper.Viper + Config *config.Server +) diff --git a/go.mod b/go.mod index b454d1b..c609190 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,8 @@ require ( github.com/spf13/viper v1.20.1 // indirect github.com/subosito/gotenv v1.6.0 // indirect go.uber.org/atomic v1.9.0 // indirect - go.uber.org/multierr v1.9.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect golang.org/x/sys v0.29.0 // indirect golang.org/x/text v0.21.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 51edcb7..c500305 100644 --- a/go.sum +++ b/go.sum @@ -27,6 +27,10 @@ go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= diff --git a/main.go b/main.go index f7c06d3..b71d09a 100644 --- a/main.go +++ b/main.go @@ -3,9 +3,12 @@ package main import ( "fmt" "sundynix-go/core" + "sundynix-go/global" ) func main() { - cfg := core.Viper() - fmt.Println(cfg.DB) + //初始化viper + global.Viper = core.Viper() + fmt.Println(global.Config.Mysql) + fmt.Println(global.Config.Redis) }