聊聊Golang中很好用的viper配置模塊
前言
viper 支持Yaml、Json、 TOML、HCL 等格式,讀取非常的方便。
安裝
go get github.com/spf13/viper
如果提示找不到golang.org/x/text/這個(gè)庫(kù),是因?yàn)間olang.org/x/text/這個(gè)庫(kù)在GitHub上托管的路徑不一致。
解決辦法:
可以從https://github.com/golang/text下載源碼下來(lái),然后到$GOPATH/src下面創(chuàng)建golang.org/x/文件夾(已存在的忽略),把壓縮包的文件解壓到golang.org/x/文件夾之下。
然后執(zhí)行 go install -x golang.org/x/text 即可解決:
正文
初始結(jié)構(gòu)目錄如下:

準(zhǔn)備測(cè)試使用的yaml文件,注意yaml的格式十分嚴(yán)格,主要是每個(gè)冒號(hào)后面必須要有空格,數(shù)組前要加“-”號(hào)表示連續(xù)(注意減號(hào)后面也有空格),內(nèi)容如下:
TimeStamp: "2018-10-18 10:09:23" Address: "Shenzhen" Postcode: 518000 CompanyInfomation: Name: "Sunny" MarketCapitalization: 50000000 EmployeeNum: 200 Department: - "Finance" - "Design" - "Program" - "Sales" IsOpen: false
讀取yaml文件:
package main
import (
"github.com/spf13/viper"
"fmt"
)
func main() {
//讀取yaml文件
v := viper.New()
//設(shè)置讀取的配置文件
v.SetConfigName("linux_config")
//添加讀取的配置文件路徑
v.AddConfigPath("./config/")
//windows環(huán)境下為%GOPATH,linux環(huán)境下為$GOPATH
v.AddConfigPath("$GOPATH/src/")
//設(shè)置配置文件類型
v.SetConfigType("yaml")
if err := v.ReadInConfig();err != nil {
fmt.Printf("err:%s\n",err)
}
fmt.Printf(
`
TimeStamp:%s
CompanyInfomation.Name:%s
CompanyInfomation.Department:%s `,
v.Get("TimeStamp"),
v.Get("CompanyInfomation.Name"),
v.Get("CompanyInfomation.Department"),
)
/*
result:
TimeStamp:2018-10-18 10:09:23
CompanyInfomation.Name:Sunny
CompanyInfomation.Department:[Finance Design Program Sales]
*/
}
也可以直接反序列化為Struct,非常的方便:
package main
import (
"github.com/spf13/viper"
"fmt"
)
func main() {
//讀取yaml文件
v := viper.New()
//設(shè)置讀取的配置文件
v.SetConfigName("linux_config")
//添加讀取的配置文件路徑
v.AddConfigPath("./config/")
//windows環(huán)境下為%GOPATH,linux環(huán)境下為$GOPATH
v.AddConfigPath("$GOPATH/src/")
//設(shè)置配置文件類型
v.SetConfigType("yaml")
if err := v.ReadInConfig();err != nil {
fmt.Printf("err:%s\n",err)
}
fmt.Printf( `
TimeStamp:%s
CompanyInfomation.Name:%s
CompanyInfomation.Department:%s `,
v.Get("TimeStamp"),
v.Get("CompanyInfomation.Name"),
v.Get("CompanyInfomation.Department"),
)
/*
result:
TimeStamp:2018-10-18 10:09:23
CompanyInfomation.Name:Sunny
CompanyInfomation.Department:[Finance Design Program Sales]
*/
//反序列化
parseYaml(v)
}
type CompanyInfomation struct{
Name string
MarketCapitalization int64
EmployeeNum int64
Department []interface{}
IsOpen bool
}
type YamlSetting struct{
TimeStamp string
Address string
Postcode int64
CompanyInfomation CompanyInfomation
}
func parseYaml(v *viper.Viper){
var yamlObj YamlSetting;
if err := v.Unmarshal(&yamlObj) ; err != nil{
fmt.Printf("err:%s",err)
}
fmt.Println(yamlObj)
/*
result:
{2018-10-18 10:09:23 Shenzhen 518000 {Sunny 50000000 200 [Finance Design Program Sales] false}}
*/
}
viper也提供了讀取Command Line參數(shù)的功能:
package main
import (
"github.com/spf13/pflag"
"github.com/spf13/viper"
"fmt"
)
func main() {
pflag.String("hostAddress", "127.0.0.1", "Server running address")
pflag.Int64("port", 8080, "Server running port")
pflag.Parse()
viper.BindPFlags(pflag.CommandLine)
fmt.Printf("hostAddress :%s , port:%s", viper.GetString("hostAddress"), viper.GetString("port"))
/*
example:
go run main2.go --hostAddress=192.192.1.10 --port=9000
help:
Usage of /tmp/go-build183981952/b001/exe/main:
--hostAddress string Server running address (default "127.0.0.1")
--port int Server running port (default 8080)
*/
}
很多時(shí)候,我們服務(wù)器啟動(dòng)之后,如果臨時(shí)想修改某些配置參數(shù),需要重啟服務(wù)器才能生效,但是viper提供了監(jiān)聽(tīng)函數(shù),可以免重啟修改配置參數(shù),非常的實(shí)用:
package main
import (
"github.com/spf13/viper"
"fmt"
"golang.org/x/net/context"
"github.com/fsnotify/fsnotify"
)
func main() {
//讀取yaml文件
v := viper.New()
//設(shè)置讀取的配置文件
v.SetConfigName("linux_config")
//添加讀取的配置文件路徑
v.AddConfigPath("./config/")
//windows環(huán)境下為%GOPATH,linux環(huán)境下為$GOPATH
v.AddConfigPath("$GOPATH/src/")
//設(shè)置配置文件類型
v.SetConfigType("yaml")
if err := v.ReadInConfig(); err != nil {
fmt.Printf("err:%s\n", err)
}
//創(chuàng)建一個(gè)信道等待關(guān)閉(模擬服務(wù)器環(huán)境)
ctx, _ := context.WithCancel(context.Background())
//cancel可以關(guān)閉信道
//ctx, cancel := context.WithCancel(context.Background())
//設(shè)置監(jiān)聽(tīng)回調(diào)函數(shù)
v.OnConfigChange(func(e fsnotify.Event) {
fmt.Printf("config is change :%s \n", e.String())
//cancel()
})
//開(kāi)始監(jiān)聽(tīng)
v.WatchConfig()
//信道不會(huì)主動(dòng)關(guān)閉,可以主動(dòng)調(diào)用cancel關(guān)閉
<-ctx.Done()
/*
result:
config is change :"/home/share/go/Viper/config/linux_config.yaml": CREATE
config is change :"/home/share/go/Viper/config/linux_config.yaml": CREATE
*/
}
完結(jié)
viper還有許多好用的功能,此文章只是舉例說(shuō)明了很小的部分。
補(bǔ)充:viper-配置信息處理框架(golang)
項(xiàng)目地址https://github.com/spf13/viper
1. viper
viper讀取配置信息的優(yōu)先級(jí)順序,從高到底:
顯式調(diào)用Set函數(shù)
命令行參數(shù)
環(huán)境變量
配置文件
key/value存儲(chǔ)系統(tǒng)
默認(rèn)值
2. 設(shè)置值
(1)設(shè)置默認(rèn)值
viper.SetDefault("ContentDir", "content")
...
(2)讀取配置文件
viper.SetConfigName("xxx") // 設(shè)置配置文件名,不要帶后綴
viper.AddConfigPath("/path") // 第一個(gè)搜索路徑
viper.AddConfigPath("../etc") // 設(shè)置為相對(duì)路徑
err := viper.ReadInConfig() // 搜索路徑,并讀取配置數(shù)據(jù)
(3)***監(jiān)視配置文件
viper支持應(yīng)用程序運(yùn)行時(shí)擁有讀取配置文件的能力
viper實(shí)例通過(guò)WatchConfig函數(shù):
viper.WatchConfig()
viper.OnConfigChange(func(e fsnotify.Event)) {
fmt.Println("Config file changed:", e.Name)
})
(4)Set調(diào)用
viper.Set("Verbose", true)
viper.Set("LogFile", LogFile)
(5)綁定命令行參數(shù)
***viper支持綁定pflags參數(shù)【pflags是一個(gè)命令行參數(shù)解析庫(kù)】
serveCmd.Flags().Int("port", 1138, "Port to run Application server on")
viper.BindPFlag("port", serverCmd.Flags().Lookup("port"))
3. 獲取值
Get(key string) : interface{}
GetBool(key string) : bool
GetFloat64(key string) : float64
GetInt(key string) : int
GetString(key string) : string
GetStringMap(key string) : map[string]interface{}
GetStringMapString(key string) : map[string]string
GetStringSlice(key string) : []string
GetTime(key string) : time.Time
GetDuration(key string) : time.Duration
IsSet(key string) : bool
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。
相關(guān)文章
go語(yǔ)言實(shí)現(xiàn)的memcache協(xié)議服務(wù)的方法
這篇文章主要介紹了go語(yǔ)言實(shí)現(xiàn)的memcache協(xié)議服務(wù)的方法,實(shí)例分析了Go語(yǔ)言使用memcache的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03
golang變量uint、int大小溢出后的結(jié)果方式
在Go語(yǔ)言中,變量的大小溢出后,`uint`類型會(huì)回繞到最小值,而`int`類型會(huì)回繞到最大值的相反數(shù),例如,`uint8`溢出后會(huì)變成0,`int64`溢出后會(huì)變成最小的負(fù)數(shù)2024-12-12
Go語(yǔ)言服務(wù)器開(kāi)發(fā)之客戶端向服務(wù)器發(fā)送數(shù)據(jù)并接收返回?cái)?shù)據(jù)的方法
這篇文章主要介紹了Go語(yǔ)言服務(wù)器開(kāi)發(fā)之客戶端向服務(wù)器發(fā)送數(shù)據(jù)并接收返回?cái)?shù)據(jù)的方法,實(shí)例分析了客戶端的開(kāi)發(fā)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-02-02
Golang實(shí)現(xiàn)gRPC的Proxy的原理解析
gRPC是Google開(kāi)始的一個(gè)RPC服務(wù)框架, 是英文全名為Google Remote Procedure Call的簡(jiǎn)稱,廣泛的應(yīng)用在有RPC場(chǎng)景的業(yè)務(wù)系統(tǒng)中,這篇文章主要介紹了Golang實(shí)現(xiàn)gRPC的Proxy的原理,需要的朋友可以參考下2021-09-09
Go語(yǔ)言操作Excel的實(shí)現(xiàn)示例
excelize是一個(gè)功能豐富且易于使用的Go語(yǔ)言庫(kù),它極大地簡(jiǎn)化了Excel文件的讀寫(xiě)操作,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-12-12
如何使用go實(shí)現(xiàn)創(chuàng)建WebSocket服務(wù)器
文章介紹了如何使用Go語(yǔ)言和gorilla/websocket庫(kù)創(chuàng)建一個(gè)簡(jiǎn)單的WebSocket服務(wù)器,并實(shí)現(xiàn)商品信息的實(shí)時(shí)廣播,感興趣的朋友一起看看吧2024-11-11

