在go语言中参数配置解决方案:viper
Go  /  管理员 发布于 1年前   472
在go语言应用中使用viper包来获取配置文件的配置信息,以及实现开发模式下的配置和上线产品如何使用进行viper做配置映射。
简单介绍一下viper
Viper是Go应用程序(包括 12 要素应用程序)的完整配置解决方案。
它设计用于在应用程序中运行,可以处理所有类型的配置需求和格式。
Viper git地址:
https://github.com/spf13/viper
进入步骤
安装viper
go get github.com/spf13/viper
目录结构:
ch1
├── config.yaml //配置文件
└── main.go //viper读取配置
config.yaml:
name: 'user-web'
mysql:
host: '127.0.0.1'
port: 3306
main.go:
package main
import (
"fmt"
"github.com/spf13/viper"
)
type mysqlConfig struct {
Host string `mapstructure:"host"`
Port int `mapstructure:"port"`
}
//ServerConfig 将配置文件内容映射为struct
type ServerConfig struct {
ServerName string `mapstructure:"name"`
SqlConfig mysqlConfig `mapstructure:"mysql"`
}
func main() {
//new对象
v := viper.New()
//读取配置文件
v.SetConfigFile("viper_test/ch1/config.yaml")
if err := v.ReadInConfig(); err != nil {
panic(err)
}
ServerConfig := ServerConfig{}
v.Unmarshal(&ServerConfig)
fmt.Println(ServerConfig)
}
在上述代码中我们定义了两个结构体:
type mysqlConfig struct {
Host string `mapstructure:"host"`
Port int `mapstructure:"port"`
}
//ServerConfig 将配置文件内容映射为struct
type ServerConfig struct {
ServerName string `mapstructure:"name"`
SqlConfig mysqlConfig `mapstructure:"mysql"`
}
这两个结构体用来做配置映射,这里使用mapstructure为配置做tag
完整代码:
package main
import (
"fmt"
"github.com/spf13/viper"
)
type mysqlConfig struct {
Host string `mapstructure:"host"`
Port int `mapstructure:"port"`
}
//ServerConfig 将配置文件内容映射为struct
type ServerConfig struct {
ServerName string `mapstructure:"name"`
SqlConfig mysqlConfig `mapstructure:"mysql"`
}
func main() {
//new一个viper对象
v := viper.New()
//获取配置文件
v.SetConfigFile("viper_test/ch1/config.yaml")
//将配置读入viper对象中
if err := v.ReadInConfig(); err != nil {
panic(err)
}
ServerConfig := ServerConfig{}
//将读取到的配置信息映射至ServerConfig中
v.Unmarshal(&ServerConfig)
fmt.Println(ServerConfig)
}
输出:
{user-web {127.0.0.1 3306}}
实时监控配置(这个场景在某些时候是非常有用的)
viper为我们提供了实时监控配置的功能
v.WatchConfig()
v.OnConfigChange(func(e fsnotify.Event) {
fmt.Println("配置变化:", e)
_ = v.ReadInConfig()
v.Unmarshal(&ServerConfig)
fmt.Println(ServerConfig)
})
事例:
package main
import (
"fmt"
"time"
"github.com/fsnotify/fsnotify"
"github.com/spf13/viper"
)
type mysqlConfig struct {
Host string `mapstructure:"host"`
Port int `mapstructure:"port"`
}
//ServerConfig 将配置文件内容映射为struct
type ServerConfig struct {
ServerName string `mapstructure:"name"`
SqlConfig mysqlConfig `mapstructure:"mysql"`
}
func main() {
//new对象
v := viper.New()
//读取配置文件
v.SetConfigFile("viper_test/ch1/config.yaml")
if err := v.ReadInConfig(); err != nil {
panic(err)
}
ServerConfig := ServerConfig{}
v.Unmarshal(&ServerConfig)
fmt.Println(ServerConfig)
v.WatchConfig()
v.OnConfigChange(func(e fsnotify.Event) {
fmt.Println("配置变化:", e)
_ = v.ReadInConfig()
v.Unmarshal(&ServerConfig)
fmt.Println(ServerConfig)
})
//延迟程序退出时间
time.Sleep(300 * time.Second)
}
运行程序后我们对port进行更改,会有如下输出:
{user-web {127.0.0.1 3306}}
配置变化: WRITE "viper_test/ch1/config.yaml"
{user-web {127.0.0.1 3303}}
配置变化: WRITE "viper_test/ch1/config.yaml"
{user-web {127.0.0.1 3306}}
线上线下环境隔离
目录结构:
ch02
├── config-debug.yaml //开发环境
├── config-por.yaml //线上环境
└── main.go
config-debug.yaml:
name: 'user-web-debug'
mysql:
host: '127.0.0.1'
port: 3306
config-por.yaml:
name: 'user-web'
mysql:
host: '195.1.43.12'
port: 2000
根据条件读写线上\线下配置并做监控
package main
import (
"fmt"
"time"
"github.com/fsnotify/fsnotify"
"github.com/spf13/viper"
)
//将配置文件嵌套映射
type MysqlServerConfig struct {
Host string `mapstructure:"host"`
Port int `mapstructure:"port"`
}
//将配置文件内容映射为struct
type ServerConfig struct {
ServerName string `mapstructure:"name"`
Mysql MysqlServerConfig `mapstructure:"mysql"`
}
//通过环境变量,将线上线下环境隔离
func GetEnvInfo(env string) bool {
viper.AutomaticEnv()
return viper.GetBool(env)
}
func main() {
debug := GetEnvInfo("MXSHOP_DEBUG")
configFilePrefix := "config"
//默认为线上配置
configFileName := fmt.Sprintf("viper_test/ch02/%s-por.yaml", configFilePrefix)
if debug {
configFileName = fmt.Sprintf("viper_test/ch02/%s-debug.yaml", configFilePrefix)
}
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)
v.WatchConfig()
v.OnConfigChange(func(e fsnotify.Event) {
fmt.Println("配置变化:", e)
_ = v.ReadInConfig()
v.Unmarshal(&ServerConfig)
fmt.Println(ServerConfig)
})
time.Sleep(300 * time.Second)
}
完,有需要或者有兴趣可以一试。
122 在
学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..123 在
Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..原梓番博客 在
在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..博主 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..1111 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
Copyright·© 2019 侯体宗版权所有·
粤ICP备20027696号