当前位置 博文首页 > 聊聊Golang中很好用的viper配置模块

    聊聊Golang中很好用的viper配置模块

    作者:龙舞飞扬v 时间:2021-02-09 06:26

    前言

    viper 支持Yaml、Json、 TOML、HCL 等格式,读取非常的方便。

    安装

    go get github.com/spf13/viper

    如果提示找不到golang.org/x/text/这个库,是因为golang.org/x/text/这个库在GitHub上托管的路径不一致。

    解决办法:

    可以从https://github.com/golang/text下载源码下来,然后到$GOPATH/src下面创建golang.org/x/文件夹(已存在的忽略),把压缩包的文件解压到golang.org/x/文件夹之下。

    然后执行 go install -x golang.org/x/text 即可解决:

    正文

    初始结构目录如下:

    准备测试使用的yaml文件,注意yaml的格式十分严格,主要是每个冒号后面必须要有空格,数组前要加“-”号表示连续(注意减号后面也有空格),内容如下:

    TimeStamp: "2018-10-18 10:09:23"
    Address: "Shenzhen"
    Postcode: 518000
    CompanyInfomation:
     Name: "Sunny"
     MarketCapitalization: 50000000
     EmployeeNum: 200
     Department:
     - "Finance"
     - "Design"
     - "Program"
     - "Sales"
     IsOpen: false

    读取yaml文件:

    package main 
    import (
     "github.com/spf13/viper"
     "fmt"
    )
     
    func main() {
     //读取yaml文件
     v := viper.New()
     //设置读取的配置文件
     v.SetConfigName("linux_config")
     //添加读取的配置文件路径
     v.AddConfigPath("./config/")
     //windows环境下为%GOPATH,linux环境下为$GOPATH
     v.AddConfigPath("$GOPATH/src/")
     //设置配置文件类型
     v.SetConfigType("yaml")
     
     if err := v.ReadInConfig();err != nil {
     fmt.Printf("err:%s\n",err)
     }
     
     fmt.Printf(
     `
     TimeStamp:%s
     CompanyInfomation.Name:%s
     CompanyInfomation.Department:%s `,
     v.Get("TimeStamp"),
     v.Get("CompanyInfomation.Name"),
     v.Get("CompanyInfomation.Department"),
     ) 
     /*
     result:
     TimeStamp:2018-10-18 10:09:23
     CompanyInfomation.Name:Sunny
     CompanyInfomation.Department:[Finance Design Program Sales]
     */ 
    }

    也可以直接反序列化为Struct,非常的方便:

    package main 
    import (
     "github.com/spf13/viper"
     "fmt"
    )
     
    func main() {
     //读取yaml文件
     v := viper.New()
     //设置读取的配置文件
     v.SetConfigName("linux_config")
     //添加读取的配置文件路径
     v.AddConfigPath("./config/")
     //windows环境下为%GOPATH,linux环境下为$GOPATH
     v.AddConfigPath("$GOPATH/src/")
     //设置配置文件类型
     v.SetConfigType("yaml") 
     if err := v.ReadInConfig();err != nil {
     fmt.Printf("err:%s\n",err)
     }
     
     fmt.Printf( `
     TimeStamp:%s
     CompanyInfomation.Name:%s
     CompanyInfomation.Department:%s `,
     v.Get("TimeStamp"),
     v.Get("CompanyInfomation.Name"),
     v.Get("CompanyInfomation.Department"),
     ) 
     /*
     result:
     TimeStamp:2018-10-18 10:09:23
     CompanyInfomation.Name:Sunny
     CompanyInfomation.Department:[Finance Design Program Sales]
     */ 
     //反序列化
     parseYaml(v) 
    }
     
    type CompanyInfomation struct{
     Name string
     MarketCapitalization int64
     EmployeeNum int64
     Department []interface{}
     IsOpen bool
    }
     
    type YamlSetting struct{
     TimeStamp string
     Address string
     Postcode int64
     CompanyInfomation CompanyInfomation
    } 
     
    func parseYaml(v *viper.Viper){
     var yamlObj YamlSetting;
     if err := v.Unmarshal(&yamlObj) ; err != nil{
     fmt.Printf("err:%s",err)
     }
     fmt.Println(yamlObj)
     /*
     result:
     {2018-10-18 10:09:23 Shenzhen 518000 {Sunny 50000000 200 [Finance Design Program Sales] false}}
     */
    }

    viper也提供了读取Command Line参数的功能:

    package main 
    import (
     "github.com/spf13/pflag"
     "github.com/spf13/viper"
     "fmt"
    )
     
    func main() {
     pflag.String("hostAddress", "127.0.0.1", "Server running address")
     pflag.Int64("port", 8080, "Server running port")
     pflag.Parse()
     
     viper.BindPFlags(pflag.CommandLine)
     fmt.Printf("hostAddress :%s , port:%s", viper.GetString("hostAddress"), viper.GetString("port"))
     /*
     example:
     go run main2.go --hostAddress=192.192.1.10 --port=9000
     help:
     Usage of /tmp/go-build183981952/b001/exe/main:
      --hostAddress string Server running address (default "127.0.0.1")
      --port int    Server running port (default 8080)
     */
     }

    很多时候,我们服务器启动之后,如果临时想修改某些配置参数,需要重启服务器才能生效,但是viper提供了监听函数,可以免重启修改配置参数,非常的实用:

    package main 
    import (
     "github.com/spf13/viper"
     "fmt"
     "golang.org/x/net/context"
     "github.com/fsnotify/fsnotify"
    )
     
    func main() {
     //读取yaml文件
     v := viper.New()
     //设置读取的配置文件
     v.SetConfigName("linux_config")
     //添加读取的配置文件路径
     v.AddConfigPath("./config/")
     //windows环境下为%GOPATH,linux环境下为$GOPATH
     v.AddConfigPath("$GOPATH/src/")
     //设置配置文件类型
     v.SetConfigType("yaml")
     
     if err := v.ReadInConfig(); err != nil {
     fmt.Printf("err:%s\n", err)
     }
     
     //创建一个信道等待关闭(模拟服务器环境)
     ctx, _ := context.WithCancel(context.Background())
     //cancel可以关闭信道
     //ctx, cancel := context.WithCancel(context.Background())
     //设置监听回调函数
     v.OnConfigChange(func(e fsnotify.Event) {
     fmt.Printf("config is change :%s \n", e.String())
     //cancel()
     })
     //开始监听
     v.WatchConfig()
     //信道不会主动关闭,可以主动调用cancel关闭
     <-ctx.Done()
     
     /*
     result:
     config is change :"/home/share/go/Viper/config/linux_config.yaml": CREATE 
     config is change :"/home/share/go/Viper/config/linux_config.yaml": CREATE
     */
    }

    完结

    viper还有许多好用的功能,此文章只是举例说明了很小的部分。

    补充:viper-配置信息处理框架(golang)

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

    1. viper

    viper读取配置信息的优先级顺序,从高到底:

    显式调用Set函数

    命令行参数

    环境变量

    配置文件

    key/value存储系统

    默认值

    2. 设置值

    (1)设置默认值

    viper.SetDefault("ContentDir", "content")

    ...

    (2)读取配置文件

    viper.SetConfigName("xxx")  // 设置配置文件名,不要带后缀
    viper.AddConfigPath("/path")  // 第一个搜索路径
    viper.AddConfigPath("../etc")  // 设置为相对路径
    err := viper.ReadInConfig()  // 搜索路径,并读取配置数据

    (3)***监视配置文件

    viper支持应用程序运行时拥有读取配置文件的能力

    viper实例通过WatchConfig函数:

    viper.WatchConfig()
    viper.OnConfigChange(func(e fsnotify.Event)) {
      fmt.Println("Config file changed:", e.Name)
    })

    (4)Set调用

    viper.Set("Verbose", true)

    viper.Set("LogFile", LogFile)

    (5)绑定命令行参数

    ***viper支持绑定pflags参数【pflags是一个命令行参数解析库】

    serveCmd.Flags().Int("port", 1138, "Port to run Application server on")

    viper.BindPFlag("port", serverCmd.Flags().Lookup("port"))

    3. 获取值

    Get(key string) : interface{}
    GetBool(key string) : bool
    GetFloat64(key string) : float64
    GetInt(key string) : int
    GetString(key string) : string
    GetStringMap(key string) : map[string]interface{}
    GetStringMapString(key string) : map[string]string
    GetStringSlice(key string) : []string
    GetTime(key string) : time.Time
    GetDuration(key string) : time.Duration
    IsSet(key string) : bool
    

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持站长博客。如有错误或未考虑完全的地方,望不吝赐教。

    js
    下一篇:没有了