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

全栈运维 · · 2106 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

具体为什么使用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)
}

第一次执行结果

yaml.v2

第二次执行结果

viper

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

image.png

结果说明

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

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


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

本文来自:简书

感谢作者:全栈运维

查看原文:Golang加载yaml类型配置文件问题

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2106 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传