结合viper获取不同的配置文件

198 阅读2分钟

viper获取配置文件信息

1.下载viper

go get github.com/spf13/viper

2.编写一个yaml的配置文件config.yaml

database:
  host: 127.0.0.1
  user: root
  dbname: test
  pwd: 123456

3. main.go

package main
 
import (
   "fmt"
   "os"
 
   "github.com/spf13/viper"
)
 
func main() {
   //获取项目的执行路径
   path, err := os.Getwd()
   if err != nil {
      panic(err)
   }
 
   config := viper.New()
 
   config.AddConfigPath(path)     //设置读取的文件路径
   config.SetConfigName("config") //设置读取的文件名
   config.SetConfigType("yaml")   //设置文件的类型
   //尝试进行配置读取
   if err := config.ReadInConfig(); err != nil {
      panic(err)
   }
 
   //打印文件读取出来的内容:
   fmt.Println(config.Get("database.host"))
   fmt.Println(config.Get("database.user"))
   fmt.Println(config.Get("database.dbname"))
   fmt.Println(config.Get("database.pwd"))
 
}

viper获取命令行参数

func main() {
    viper.AutomaticEnv()
    viper.GetString(env)
}

项目实战

全局结构体

package global
​
import (
    "github.com/go-redis/redis/v8"
    "github.com/patrickmn/go-cache"
    "github.com/songzhibin97/gkit/cache/local_cache"
    "go.uber.org/zap"
    "golang.org/x/sync/singleflight"
    "gorm.io/gorm"
    "sync"
    "xkginweb/commons/parse"
)
​
var (
    Yaml       map[string]interface{}
    Config     *parse.Config
)
​
package parse
​
// 配置接下入口
type Config struct {
    Database Database `mapstructure:"database" json:"database" yaml:"database"`
    Ksd      Ksd      `mapstructure:"ksd" json:"ksd" yaml:"ksd"`
    NoSQL    NoSQL    `mapstructure:"nosql" json:"nosql" yaml:"nosql"`
    Local    Local    `mapstructure:"local" json:"local" yaml:"local"`
}
​
type Local struct {
    Path       string `mapstructure:"path" json:"path" yaml:"path"`                   // 本地文件访问路径
    Fileserver string `mapstructure:"fileserver" json:"fileserver" yaml:"fileserver"` // 本地文件访问路径
    StorePath  string `mapstructure:"store-path" json:"store-path" yaml:"store-path"` // 本地文件存储路径
}
​

初始化方法

package initilization
​
import (
    "fmt"
    "github.com/beego/beego/v2/adapter/logs"
    "github.com/fsnotify/fsnotify"
    "github.com/spf13/viper"
    "os"
    "xkginweb/global"
)
​
func GetEnvInfo(env string) string {
    viper.AutomaticEnv()
    return viper.GetString(env)
}
​
func InitViper(args map[string]any) {
    //获取项目的执行路径
    path, err := os.Getwd()
    if err != nil {
        panic(err)
    }
    config := viper.New()
    //config.AddConfigPath(path + "/conf") //设置读取的文件路径
    //config.SetConfigName("application")  //设置读取的文件名
    //config.SetConfigType("yaml")         //设置文件的类型
    logs.Info("你激活的环境是:" + GetEnvInfo("env"))
    config.SetConfigFile(path + "/conf/application-" + GetEnvInfo("env") + ".yaml")
    //尝试进行配置读取
    if err := config.ReadInConfig(); err != nil {
        panic(err)
    }
​
    config.WatchConfig()
    config.OnConfigChange(func(e fsnotify.Event) {
        fmt.Println("config file changed:", e.Name)
        if err = config.Unmarshal(&global.Config); err != nil {
            fmt.Println(err)
        }
    })
​
    // 这里才是把yaml配置文件解析放入到Config对象的过程---map---config
    if err = config.Unmarshal(&global.Config); err != nil {
        fmt.Println(err)
    }
​
    // 打印文件读取出来的内容:
    keys := config.AllKeys()
    dataMap := make(map[string]interface{})
    for _, key := range keys {
        fmt.Println("yaml存在的key是: " + key)
        dataMap[key] = config.Get(key)
    }
​
    // 用环境变量覆盖
    // 命令行参数覆盖 boot
    port := args["server.port"].(int)
    if port != -1 {
        dataMap["server.port"] = port
    }
​
    global.Yaml = dataMap
​
}
​

func main() {
    var env string = "dev"
    var port int = -1
   // 这里也可以使用一个结构体
   args := map[string]any{"env": env, "server.port": port}
   // 设置环境变量
   viper.SetDefault("env", env)
   // 解析配置文件 传入args主要是为了使命令行设定大于代码设定
   initilization.InitViper(args)
}