Go一站式配置管理工具Viper的使用教程

  目录

  什么是Viper

  Viper是一个方便Go语言应用程序处理配置信息的库。它可以处理多种格式的配置。它支持的特性:

  为什么要使用Viper

  在构建现代应用程序时,您不必担心配置文件格式; 你可以专注于构建出色的软件。

  Viper 可以做如下工作:

  Viper读取配置信息的优先级顺序,从高到低,如下:

  Viper 的配置项的key不区分大小写。

  项目地址:https://github.com/spf13/viper

  使用

  设置默认值

  默认值不是必须的,如果配置文件、环境变量、远程配置系统、命令行参数、Set函数都没有指定时,默认值将起作用。

  viper.SetDefault("name", "xiaoming")

  viper.SetDefault("age", "12")

  viper.SetDefault("notifyList", []string{"xiaohong","xiaoli","xiaowang"})

  读取配置文件

  Viper支持JSON、TOML、YAML、HCL和Java properties文件。

  Viper可以搜索多个路径,但目前单个Viper实例仅支持单个配置文件。

  Viper默认不搜索任何路径。

  以下是如何使用Viper搜索和读取配置文件的示例。

  路径不是必需的,但最好至少应提供一个路径,以便找到一个配置文件。

  viper.SetConfigName("dbConfig") // 设置配置文件名 (不带后缀)

  viper.AddConfigPath("/workspace/appName/") // 第一个搜索路径

  viper.AddConfigPath("/workspace/appName1") // 可以多次调用添加路径

  viper.AddConfigPath(".") // 比如添加当前目录

  err := viper.ReadInConfig() // 搜索路径,并读取配置数据

  if err != nil {

  panic(fmt.Errorf("Fatal error config file: %s

  ", err))

  }

  监视配置文件,重新读取配置数据

  Viper支持让你的应用程序在运行时拥有读取配置文件的能力。

  只需要调用viper实例的WatchConfig函数,你也可以指定一个回调函数来获得变动的通知。

  viper.WatchConfig()

  viper.OnConfigChange(func(e fsnotify.Event) {

  fmt.Println("Config file changed:", e.Name)

  })

  从 io.Reader 中读取配置

  Viper预先定义了许多配置源,例如文件、环境变量、命令行参数和远程K / V存储系统。也可以实现自己的配置源,并提供给viper。

  现在有如下yaml文件:

  userName: "xiaoming"

  address: "广州市XXX"

  sex: 1

  company:

  name: "xxx"

  employeeId: 1000

  department:

  - "技术部"

  读取文件的代码如下:

  package main

  import (

  "fmt"

  "github.com/spf13/viper"

  )

  type UserInfo struct {

  UserName string

  Address string

  Sex byte

  Company Company

  }

  type Company struct {

  Name string

  EmployeeId int

  Department []interface{}

  }

  func main() {

  //读取yaml文件

  v := viper.New()

  //设置读取的配置文件名

  v.SetConfigName("userInfo")

  //windows环境下为%GOPATH,linux环境下为$GOPATH

  v.AddConfigPath("/Users/yangyue/workspace/go/src/webDemo/")

  //设置配置文件类型

  v.SetConfigType("yaml")

  if err := v.ReadInConfig();err != nil {

  fmt.Printf("err:%s

  ",err)

  }

  fmt.Printf("userName:%s sex:%s company.name:%s

  ", v.Get("userName"), v.Get("sex"), v.Get("company.name"))

  //也可以直接反序列化为Struct

  var userInfo UserInfo

  if err := v.Unmarshal(&userInfo) ; err != nil{

  fmt.Printf("err:%s",err)

  }

  fmt.Println(userInfo)

  }

  上面的代码使用两种方式获取配置文件:第一种直接解析为key,value;第二种你可以手动的反序列化为Struct。

  从命令行参数中读取

  package main

  import (

  "fmt"

  "github.com/spf13/pflag"

  "github.com/spf13/viper"

  )

  func main() {

  pflag.String("ip", "127.0.0.1", "Server running address")

  pflag.Int64("port", 8080, "Server running port")

  pflag.Parse()

  viper.BindPFlags(pflag.CommandLine)

  fmt.Printf("ip :%s , port:%s", viper.GetString("ip"), viper.GetString("port"))

  }

  命令行执行上面程序:

  # go run test.go --ip=192.168.7.3 --port=3306

  可以看到输出的是我们自定义的参数。

  读取环境变量参数

  一般获取环境变量使用包,比如:

  getenv := os.Getenv("JAVA_HOME")

  fmt.Print(getenv)

  Viper也提供了一种方式:

  //表示 先预加载匹配的环境变量

  viper.AutomaticEnv()

  //读取已经加载到default中的环境变量

  if env := viper.Get("JAVA_HOME"); env == nil {

  println("error!")

  } else {

  fmt.Printf("%#v

  ", env)

  }

  由获取环境变量我们是不是可以想到多环境参数配置呢?针对线上环境,开发环境分别加载不同yml中的参数。

  func initConfig() (err error) {

  env := os.Getenv("GO_ENV")

  viper.SetConfigName(env)

  viper.AddConfigPath("http://www.jb51.net/jiaoben/configs")

  viper.SetConfigType("yml")

  err = viper.ReadInConfig()

  return

  }

  因为无论是线上环境还是测试环境,肯定有一些参数是公共不变的,那么这一部分参数是否可以抽出来作为一个单独的配置文件呢。所以这样配置文件可以分为两个部分:

  "github.com/gobuffalo/packr"

  func initConfig() (err error) {

  box := packr.NewBox("http://www.jb51.net/jiaoben/configs")

  configType := "yml"

  defaultConfig, _ := box.Find("default.yml")

  v := viper.New()

  v.SetConfigType(configType)

  err = v.ReadConfig(bytes.NewReader(defaultConfig))

  if err != nil {

  return

  }

  configs := v.AllSettings()

  // 将default中的配置全部以默认配置写入

  for k, v := range configs {

  viper.SetDefault(k, v)

  }

  env := os.Getenv("GO_ENV")

  // 根据配置的env读取相应的配置信息

  if env != "" {

  envConfig, _ := box.Find(env + ".yml")

  viper.SetConfigType(configType)

  err = viper.ReadConfig(bytes.NewReader(envConfig))

  if err != nil {

  return

  }

  }

  return

  }

  首先读取default.yml中的参数,将其写入default中。然后再根据环境变量读取不同环境中的参数。

  这里使用了packr包,packr包的作用在于将静态资源打包至应用程序中。

  以上就是Go一站式配置管理工具Viper的使用教程的详细内容,更多关于Go Viper的资料请关注脚本之家其它相关文章!

  您可能感兴趣的文章: