具体为什么使用yaml类型作为配置文件,有没有更好的配置文件类型,不是这篇研究的主旨。这边主要是介绍在使用
yaml.v2
和viper
两种方式加载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)
}
第一次执行结果
第二次执行结果
第三次执行结果(第三次执行的时候修改Configuration
结构体中的SMTPHost
为 SMTP_Host
)
结果说明
- 从两次结果执行观察到,
viper
解析的时候是有格式要求的,原始配置文件中smtp_host
那么在使用viper的时候必须是SMTP_Host
,需要格式上保持一致
,SMTPHost
就解析失败; - 但是使用
yaml.v2
的时候完全没有这个问题,格式任意即可
验证代码详见 https://gitee.com/colin5063/go-learn/tree/master/20201221-yaml
有疑问加站长微信联系(非本文作者)