Go一站式配置管理工具Viper的使用教程
什么是Viper
Viper是一個(gè)方便Go語(yǔ)言應(yīng)用程序處理配置信息的庫(kù)。它可以處理多種格式的配置。它支持的特性:
- 設(shè)置默認(rèn)值
- 從JSON、TOML、YAML、HCL和Java properties文件中讀取配置數(shù)據(jù)
- 可以監(jiān)視配置文件的變動(dòng)、重新讀取配置文件
- 從環(huán)境變量中讀取配置數(shù)據(jù)
- 從遠(yuǎn)端配置系統(tǒng)中讀取數(shù)據(jù),并監(jiān)視它們(比如etcd、Consul)
- 從命令參數(shù)中讀物配置
- 從buffer中讀取
- 調(diào)用函數(shù)設(shè)置配置信息
為什么要使用Viper
在構(gòu)建現(xiàn)代應(yīng)用程序時(shí),您不必?fù)?dān)心配置文件格式; 你可以專注于構(gòu)建出色的軟件。
Viper 可以做如下工作:
- 加載并解析JSON、TOML、YAML、HCL 或 Java properties 格式的配置文件
- 可以為各種配置項(xiàng)設(shè)置默認(rèn)值
- 可以在命令行中指定配置項(xiàng)來(lái)覆蓋配置值
- 提供了別名系統(tǒng),可以不破壞現(xiàn)有代碼來(lái)實(shí)現(xiàn)參數(shù)重命名
- 可以很容易地分辨出用戶提供的命令行參數(shù)或配置文件與默認(rèn)相同的區(qū)別
Viper讀取配置信息的優(yōu)先級(jí)順序,從高到低,如下:
- 顯式調(diào)用Set函數(shù)
- 命令行參數(shù)
- 環(huán)境變量
- 配置文件
- key/value 存儲(chǔ)系統(tǒng)
- 默認(rèn)值
Viper 的配置項(xiàng)的key不區(qū)分大小寫。
項(xiàng)目地址:https://github.com/spf13/viper
使用
設(shè)置默認(rèn)值
默認(rèn)值不是必須的,如果配置文件、環(huán)境變量、遠(yuǎn)程配置系統(tǒng)、命令行參數(shù)、Set函數(shù)都沒有指定時(shí),默認(rèn)值將起作用。
viper.SetDefault("name", "xiaoming")
viper.SetDefault("age", "12")
viper.SetDefault("notifyList", []string{"xiaohong","xiaoli","xiaowang"})讀取配置文件
Viper支持JSON、TOML、YAML、HCL和Java properties文件。
Viper可以搜索多個(gè)路徑,但目前單個(gè)Viper實(shí)例僅支持單個(gè)配置文件。
Viper默認(rèn)不搜索任何路徑。
以下是如何使用Viper搜索和讀取配置文件的示例。
路徑不是必需的,但最好至少應(yīng)提供一個(gè)路徑,以便找到一個(gè)配置文件。
viper.SetConfigName("dbConfig") // 設(shè)置配置文件名 (不帶后綴)
viper.AddConfigPath("/workspace/appName/") // 第一個(gè)搜索路徑
viper.AddConfigPath("/workspace/appName1") // 可以多次調(diào)用添加路徑
viper.AddConfigPath(".") // 比如添加當(dāng)前目錄
err := viper.ReadInConfig() // 搜索路徑,并讀取配置數(shù)據(jù)
if err != nil {
panic(fmt.Errorf("Fatal error config file: %s \n", err))
}監(jiān)視配置文件,重新讀取配置數(shù)據(jù)
Viper支持讓你的應(yīng)用程序在運(yùn)行時(shí)擁有讀取配置文件的能力。
只需要調(diào)用viper實(shí)例的WatchConfig函數(shù),你也可以指定一個(gè)回調(diào)函數(shù)來(lái)獲得變動(dòng)的通知。
viper.WatchConfig()
viper.OnConfigChange(func(e fsnotify.Event) {
fmt.Println("Config file changed:", e.Name)
})從 io.Reader 中讀取配置
Viper預(yù)先定義了許多配置源,例如文件、環(huán)境變量、命令行參數(shù)和遠(yuǎn)程K / V存儲(chǔ)系統(tǒng)。也可以實(shí)現(xiàn)自己的配置源,并提供給viper。
現(xiàn)在有如下yaml文件:
userName: "xiaoming"
address: "廣州市XXX"
sex: 1
company:
name: "xxx"
employeeId: 1000
department:
- "技術(shù)部"讀取文件的代碼如下:
package main
import (
"fmt"
"github.com/spf13/viper"
)
type UserInfo struct {
UserName string
Address string
Sex byte
Company Company
}
type Company struct {
Name string
EmployeeId int
Department []interface{}
}
func main() {
//讀取yaml文件
v := viper.New()
//設(shè)置讀取的配置文件名
v.SetConfigName("userInfo")
//windows環(huán)境下為%GOPATH,linux環(huán)境下為$GOPATH
v.AddConfigPath("/Users/yangyue/workspace/go/src/webDemo/")
//設(shè)置配置文件類型
v.SetConfigType("yaml")
if err := v.ReadInConfig();err != nil {
fmt.Printf("err:%s\n",err)
}
fmt.Printf("userName:%s sex:%s company.name:%s \n", v.Get("userName"), v.Get("sex"), v.Get("company.name"))
//也可以直接反序列化為Struct
var userInfo UserInfo
if err := v.Unmarshal(&userInfo) ; err != nil{
fmt.Printf("err:%s",err)
}
fmt.Println(userInfo)
}上面的代碼使用兩種方式獲取配置文件:第一種直接解析為key,value;第二種你可以手動(dòng)的反序列化為Struct。
從命令行參數(shù)中讀取
package main
import (
"fmt"
"github.com/spf13/pflag"
"github.com/spf13/viper"
)
func main() {
pflag.String("ip", "127.0.0.1", "Server running address")
pflag.Int64("port", 8080, "Server running port")
pflag.Parse()
viper.BindPFlags(pflag.CommandLine)
fmt.Printf("ip :%s , port:%s", viper.GetString("ip"), viper.GetString("port"))
}命令行執(zhí)行上面程序:
# go run test.go --ip=192.168.7.3 --port=3306
可以看到輸出的是我們自定義的參數(shù)。
讀取環(huán)境變量參數(shù)
一般獲取環(huán)境變量使用os包,比如:
getenv := os.Getenv("JAVA_HOME")
fmt.Print(getenv)Viper也提供了一種方式:
//表示 先預(yù)加載匹配的環(huán)境變量
viper.AutomaticEnv()
//讀取已經(jīng)加載到default中的環(huán)境變量
if env := viper.Get("JAVA_HOME"); env == nil {
println("error!")
} else {
fmt.Printf("%#v\n", env)
}由獲取環(huán)境變量我們是不是可以想到多環(huán)境參數(shù)配置呢?針對(duì)線上環(huán)境,開發(fā)環(huán)境分別加載不同yml中的參數(shù)。
func initConfig() (err error) {
env := os.Getenv("GO_ENV")
viper.SetConfigName(env)
viper.AddConfigPath("./configs")
viper.SetConfigType("yml")
err = viper.ReadInConfig()
return
}因?yàn)闊o(wú)論是線上環(huán)境還是測(cè)試環(huán)境,肯定有一些參數(shù)是公共不變的,那么這一部分參數(shù)是否可以抽出來(lái)作為一個(gè)單獨(dú)的配置文件呢。所以這樣配置文件可以分為兩個(gè)部分:
"github.com/gobuffalo/packr"
func initConfig() (err error) {
box := packr.NewBox("./configs")
configType := "yml"
defaultConfig, _ := box.Find("default.yml")
v := viper.New()
v.SetConfigType(configType)
err = v.ReadConfig(bytes.NewReader(defaultConfig))
if err != nil {
return
}
configs := v.AllSettings()
// 將default中的配置全部以默認(rèn)配置寫入
for k, v := range configs {
viper.SetDefault(k, v)
}
env := os.Getenv("GO_ENV")
// 根據(jù)配置的env讀取相應(yīng)的配置信息
if env != "" {
envConfig, _ := box.Find(env + ".yml")
viper.SetConfigType(configType)
err = viper.ReadConfig(bytes.NewReader(envConfig))
if err != nil {
return
}
}
return
}首先讀取default.yml中的參數(shù),將其寫入default中。然后再根據(jù)環(huán)境變量讀取不同環(huán)境中的參數(shù)。
這里使用了packr包,packr包的作用在于將靜態(tài)資源打包至應(yīng)用程序中。
以上就是Go一站式配置管理工具Viper的使用教程的詳細(xì)內(nèi)容,更多關(guān)于Go Viper的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
golang MarshalJson的實(shí)現(xiàn)
本文主要介紹了golang MarshalJson的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-03-03
Golang棧結(jié)構(gòu)和后綴表達(dá)式實(shí)現(xiàn)計(jì)算器示例
這篇文章主要為大家介紹了Golang棧結(jié)構(gòu)和后綴表達(dá)式實(shí)現(xiàn)計(jì)算器示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
Go+Kafka實(shí)現(xiàn)延遲消息的實(shí)現(xiàn)示例
本文主要介紹了Go+Kafka實(shí)現(xiàn)延遲消息的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
Go語(yǔ)言TCP從原理到代碼實(shí)現(xiàn)詳解
這篇文章主要為大家介紹了Go語(yǔ)言TCP從原理到代碼實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
goland 實(shí)現(xiàn)websocket server的示例代碼
本文主要介紹了goland 實(shí)現(xiàn)websocket server的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06
golang切片擴(kuò)容規(guī)則實(shí)現(xiàn)
這篇文章主要介紹了golang切片擴(kuò)容規(guī)則實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
Go語(yǔ)言基礎(chǔ)模板設(shè)計(jì)模式示例詳解
這篇文章主要為大家介紹了Go語(yǔ)言基礎(chǔ)設(shè)計(jì)模式之模板模式的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2021-11-11

