5.3 viper 包配置文件使用
我们现在可以看到这个程序在启动的时候需要加载很多配置信息,那我们可以将其写到配置文件中
没中配置文件都有对应不同的库,因为每一种配置文件他都有固定的格式,所以需要通过不同的解析器
-
常见配置文件:
-
ini => 解析器
-
json => 解析器
-
yaml => 解析器
-
toml => 解析器
-
自定义格式 => 自定义解析器
-
这里我使用的是 viper
,这个包的话支持多种配置文件的解析
官方地址:https://pkg.go.dev/github.com/spf13/viper
5.3.1 viper 读取配置文件范例
5.3.1.1 yaml 格式配置文件读取初体验
1.这里通过 yaml 格式来做演示,我先创建一个 test.yaml
文件
[15:15:42 root@go day17]#mkdir testviper
[15:15:49 root@go day17]#touch testviper/test.yaml
2.编写配置文件设置
---
# mysql 配置
mysql
host10.0.0.3
port3306
username root
password"123456"
db mysql
# web 配置
web
auth
username admin
password"$2a$10$zpc7sIKlzk6G5G/IYfjPOOhmFryD6IwSplOJWUhsoZvcOdb/HrayS"
# log 配置
log
filename log/mysqld.log
max_age0
max_size1
max_backups14
compressfalse
3.然后我们就需要在程序中来读取该配置
package main
import (
"fmt"
"log"
"github.com/spf13/viper"
)
func main() {
// 定义配置格式为 yaml
viper.SetConfigType("yaml")
// 设置配置文件名称,注意这里指定配置文件不用添加后缀
// 因为他在找文件的时候通过我们指定的 name 和指定的配置文件类型来找
viper.SetConfigName("test")
// 配置多个路径下去寻找配置文件,这里是 . 也就是在当前路径下找
viper.AddConfigPath(".")
// 设置默认值,把 mysql 下的 port 字段设置为 3306,如果在配置文件中没有指定 mysql.port 属性就会读取默认值
viper.SetDefault("mysql.port", 3306)
// 解析配置文件
err := viper.ReadInConfig()
if err != nil {
log.Fatal(err)
}
// 读取配置文件,通过 get 方法来获取 mysql 信息
fmt.Println(viper.Get("mysql"))
// 只获取 mysql 下的 host 字段信息,并且是 string 类型
fmt.Println(viper.GetString("mysql.host"))
fmt.Println(viper.Get("web"))
fmt.Println(viper.Get("log"))
}
执行程序
[15:37:14 root@go testviper]#go run main.go
map[db:mysql host:10.0.0.3 password:123456 port:3306 username:root] # mysql 信息
10.0.0.3 # mysql.host 信息
map[auth:map[password:$2a$10$zpc7sIKlzk6G5G/IYfjPOOhmFryD6IwSplOJWUhsoZvcOdb/HrayS username:admin]]
map[compress:false filename:log/mysqld.log max_age:0 max_backups:14 max_size:1]
5.3.1.2 将配置文件内容读取到结构体中
package main
import (
"fmt"
"github.com/spf13/viper"
)
type Options struct {
// 定义 mysql 结构体只有两个属性 host 和 password
Mysql struct {
Host string
Password string
}
}
func main() {
viper.SetConfigType("yaml")
viper.SetConfigName("test")
viper.AddConfigPath(".")
if err := viper.ReadInConfig(); err != nil {
fmt.Println(err)
}
fmt.Println(viper.Get("mysql"))
options := &Options{}
// 通过 unmarshal 将配置文件中中的 mysql 字段下的 host 和 password 解析到 options 中
err := viper.Unmarshal(&options)
if err != nil {
fmt.Println(err)
return
}
// 将配置文件读取到结构体中
fmt.Println(options)
}
执行
[16:12:34 root@go testviper]#go run main.go
map[db:mysql host:10.0.0.3 password:123456 port:3306 username:root]
# 就已经解析到了 options 结构体中
&{{10.0.0.3 123456}}
这样的话就涉及到结构体和配置文件里面的一个对应关系,如果说配置文件中的字段和我们程序中的属性不对应的时候我们可以通过标签的方式来获取如下案例
1.编写 test2.yaml 配置文件
databases
host1.1.1.1
2.程序中通过标签指定匹配关系
package main
import (
"fmt"
"github.com/spf13/viper"
)
type Options struct {
// 定义 mysql 结构体只有两个属性 host 和 password
Mysql struct {
Host string
Password string
} `mapstructure:"databases"` // 定义标签为 databases
}
func main() {
viper.SetConfigType("yaml")
viper.SetConfigName("test2")
viper.AddConfigPath(".")
if err := viper.ReadInConfig(); err != nil {
fmt.Println(err)
}
options := &Options{}
err := viper.Unmarshal(&options)
if err != nil {
fmt.Println(err)
return
}
// 将配置文件读取到结构体中
fmt.Println(options)
}
3.执行程序
[16:24:21 root@go testviper]#go run main.go
map[db:mysql host:10.0.0.3 password:123456 port:3306 username:root]
&{{1.1.1.1 }} # 能够解析到 1.1.1.1
5.3.2 viper 写入配置文件范例
1.编写程序
package main
import (
"github.com/spf13/viper"
)
func main() {
// 定义 redis port 属性为 6479
viper.SetDefault("redis.port", 64 79)
// 定义 redis host 属性为 1.1.1.1
viper.SetDefault("redis.host", "1.1.1.1")
// 写到当前文件的 test2.yaml 文件中
viper.WriteConfigAs("./test2.yaml")
}
2.执行程序
[16:27:45 root@go testviper]#go run main.go
3.test2.yaml 文件生成