10

Golang加载yaml类型配置文件问题

 3 years ago
source link: https://studygolang.com/articles/32274
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

具体为什么使用yaml类型作为配置文件,有没有更好的配置文件类型,不是这篇研究的主旨。这边主要是介绍在使用yaml.v2viper 两种方式加载yaml类型时候遇到的问题介绍
不关注过程的朋友可以直接跳转到最后查看结果说明

配置文件介绍

demo 程序路径

| demo
| - config
| - - config.yaml
| - service
| - - config.go

config.yaml 配置文件

$ cat config/config.yaml
dsn: bamboo:Bamboo@tcp(127.0.0.1:3306)/bamboo?charset=utf8mb4&parseTime=True&loc=Local

qiniu_bucket:
qiniu_accesskey:
qiniu_secretkey:

smtp_host: smtp.exmail.qq.com
smtp_username:
smtp_password:


port: 8889
smtp:
  host: smtp.exmail.qq.com
  username:
  password:

在编写函数之前,先定义配置文件struct来对应配置文件,这是最基础的一步

type SMTPConfig struct {
    Host        string  `yaml:"host"`
    Username    string  `yaml:"username"`
    Password    string  `yaml:"password"`
}

type Configuration struct {
    DSN     string  `yaml:"dsn"`

    SMTPHost    string  `yaml:"smtp_host"`
    SMTPUsername    string  `yaml:"smtp_usernane"`
    SMTPPassword    string  `yaml:"smtp_password"`

    QiniuBucket string  `yaml:"qiniu_bucket"`
    QiniuAccessKey  string  `yaml:"qiniu_accesskey"`
    QiniuSecretKey  string  `yaml:"qiniu_secretkey"`
    Port        int `yaml:"port"`
    SMTP        SMTPConfig  `yaml:"smtp"`
}

然后定义一个全局变量configuration 来存放解析,然后定义两个函数LoadConfiguration()GetConfiguration() 分别解析和获取配置

var (
    configuration *Configuration
)
// yaml.v2
func LoadConfiguration(path string) error {}
// viper
func LoadConfigurationV2() error {}
// GetConfiguration
func GetConfiguration() *Configuration {
    return configuration
}

使用 yaml.v2

使用之前先安装对应的包

go get gopkg.in/yaml.v2

加载配置的函数

func LoadConfiguration(path string) error {
    data, err := ioutil.ReadFile(path)
    if err != nil {
        return err
    }

    var config Configuration
    err = yaml.Unmarshal(data, &config)
    if err != nil {
        return err
    }

    fmt.Println("in func(yaml.v2): ", config)
    configuration = &config
    return nil
}

使用 viper

使用之前先安装对应的包

go get github.com/spf13/viper

加载配置的函数

func LoadConfigurationV2() error {
    v := viper.New()
    v.AddConfigPath("./config/")
    v.SetConfigType("yaml")
    v.SetConfigName("config")

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


    var config Configuration
    if err := v.Unmarshal(&config); err != nil {
        return nil
    }

    fmt.Println("in func(viper): ", config)
    configuration = &config
    return nil
}

主函数执行观察结果

func main() {
    // 第一次执行 yaml.v2, 注释掉LoadConfigurationV2这一行
    path := "./config/config.yaml"
    err := LoadConfiguration(path)
    // 第二次执行 viper, 注释掉上面两行,放开下面这一行
    // err := LoadConfigurationV2()
    if err != nil {
        fmt.Println("Load configuration err ", err)
    }

    fmt.Println("in main: ", GetConfiguration().DSN)
    fmt.Println("in main: ", GetConfiguration().QiniuBucket)
    fmt.Println("in main: ", GetConfiguration().SMTP.Host)
}

第一次执行结果

ae3c9ea1b5c420b6596c9cc97baa688f.png
yaml.v2

第二次执行结果

bf7ba9d1b136795b764c7346745ffa17.png
viper

第三次执行结果(第三次执行的时候修改Configuration 结构体中的SMTPHostSMTP_Host

0b514c3c894d5919e961e9f95f6418b1.png
image.png
  • 从两次结果执行观察到,viper解析的时候是有格式要求的,原始配置文件中smtp_host 那么在使用viper的时候必须是SMTP_Host,需要格式上保持一致SMTPHost 就解析失败;
  • 但是使用yaml.v2的时候完全没有这个问题,格式任意即可

验证代码详见 https://gitee.com/colin5063/go-learn/tree/master/20201221-yaml


有疑问加站长微信联系(非本文作者)

280

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK