Viper是适用于Go应用程序的完整配置解决方案。它被设计用于在应用程序中工作,并且可以处理所有类型的配置需求和格式。它支持以下特性:
(1)设置默认值
(2)从JSON、TOML、YAML(YAML教程)、HCL、envfile和Java properties格式的配置文件读取配置信息
(3) 实时监控和重新读取配置文件(可选)
(4)从环境变量中读取
(5)从远程配置系统(etcd或Consul)读取并监控配置变化
(6)从命令行参数读取配置
(7)从buffer读取配置
(8)显式配置值
Viper安装
cpp
go get github.com/spf13/viper
简单使用
目录结构
config.yaml
cpp
name: ' user'
main.go
cpp
package main
import (
"fmt"
"github.com/spf13/viper"
)
func main() {
v := viper.New()
v.SetConfigFile("config.yaml")
if err := v.ReadInConfig(); err != nil {
panic(err)
}
fmt.Println(v.Get("name"))
}
cd到viper_test目录运行(go build main.go)
将配置文件映射成struct
cpp
package main
import (
"fmt"
"github.com/spf13/viper"
)
type ServerConfig struct {
ServerName string `mapstructure:"name"`
}
func main() {
v := viper.New()
v.SetConfigFile("config.yaml")
if err := v.ReadInConfig(); err != nil {
panic(err)
}
serverConfig := ServerConfig{}
if err := v.Unmarshal(&serverConfig); err != nil {
panic(err)
}
fmt.Println(serverConfig)
fmt.Println(v.Get("name"))
}
嵌套映射
config.yaml
cpp
name: ' user'
mysql:
host: '127.0.0.1'
port: 3306
main.go
cpp
package main
import (
"fmt"
"github.com/spf13/viper"
)
type MysqlConfig struct {
Host string `mapstruct:"host"`
Port int `mapstruct:"port"`
}
type ServerConfig struct {
ServerName string `mapstructure:"name"`
MysqlInfo MysqlConfig `mapstructure:"mysql"`
}
func main() {
v := viper.New()
v.SetConfigFile("config.yaml")
if err := v.ReadInConfig(); err != nil {
panic(err)
}
serverConfig := ServerConfig{}
if err := v.Unmarshal(&serverConfig); err != nil {
panic(err)
}
fmt.Println(serverConfig)
fmt.Println(v.Get("name"))
}
开发环境和生产环境隔离配置
设置环境变量
cpp
vim ~/.zshrc
cpp
export VIPER_DEBUG=true
cpp
source ~/.zshrc
config-pro.yaml是生产环境的路径,config-debug.yaml是开发环境的路径
cpp
package main
import (
"fmt"
"github.com/spf13/viper"
)
type ServerConfig struct {
ServerName string `mapstructure:"name"`
}
func GetEnvInfo(env string) bool {
viper.AutomaticEnv()
return viper.GetBool(env)
}
func main() {
debug := GetEnvInfo("VIPER_DEBUG")
configFileName := "config-pro.yaml"
if debug {
configFileName = "config-debug.yaml"
}
v := viper.New()
v.SetConfigFile(configFileName)
if err := v.ReadInConfig(); err != nil {
panic(err)
}
serverConfig := ServerConfig{}
if err := v.Unmarshal(&serverConfig); err != nil {
panic(err)
}
fmt.Println(serverConfig)
fmt.Println(v.Get("name"))
}
动态监听配置文件变化
运行完之后需要更改yaml文件并保存
cpp
package main
import (
"fmt"
"time"
"github.com/fsnotify/fsnotify"
"github.com/spf13/viper"
)
type MysqlConfig struct {
Host string `mapstruct:"host"`
Port int `mapstruct:"port"`
}
type ServerConfig struct {
ServerName string `mapstructure:"name"`
MysqlInfo MysqlConfig `mapstructure:"mysql"`
}
func GetEnvInfo(env string) bool {
viper.AutomaticEnv()
return viper.GetBool(env)
}
func main() {
v := viper.New()
v.SetConfigFile("config.yaml")
if err := v.ReadInConfig(); err != nil {
panic(err)
}
serverConfig := ServerConfig{}
if err := v.Unmarshal(&serverConfig); err != nil {
panic(err)
}
fmt.Println(serverConfig)
fmt.Println(v.Get("name"))
//动态监听变化
v.WatchConfig()
v.OnConfigChange(func(e fsnotify.Event) {
fmt.Println("config file changed:", e.Name)
_ = v.ReadInConfig()
_ = v.Unmarshal(&serverConfig)
fmt.Println(serverConfig)
})
time.Sleep(time.Second * 60)
}