詳解如何使用Go的Viper來解析配置信息
前言
對(duì)于現(xiàn)代應(yīng)用程序,尤其大中型的項(xiàng)目來說,在程序啟動(dòng)和運(yùn)行時(shí),往往需要傳入許多參數(shù)來控制程序的行為,我們可以通過命令行參數(shù),環(huán)境變量,配置文件等方式來將參數(shù)傳遞給程序。而Viper庫為Golang語言開發(fā)者提供了對(duì)不同數(shù)據(jù)源和不同格式的配置文件的讀取,是Go項(xiàng)目讀取配置的神器,我們今天就來講講如何使用Viper來解析配置信息。
Viper簡(jiǎn)介
Viper是適用于Go應(yīng)用程序(包括Twelve-Factor App)的完整配置解決方案。它被設(shè)計(jì)用于在應(yīng)用程序中工作,并且可以處理所有類型的配置需求和格式。它支持以下特性:
- 設(shè)置默認(rèn)值
- 從JSON、TOML、YAML、HCL、envfile和Java properties格式的配置文件讀取配置信息
- 實(shí)時(shí)監(jiān)控和重新讀取配置文件(可選)
- 從環(huán)境變量中讀取
- 從遠(yuǎn)程配置系統(tǒng)(etcd或Consul)讀取并監(jiān)控配置變化
- 從命令行參數(shù)讀取配置
- 從buffer讀取配置
- 顯式配置值
快速上手
庫的安裝
viper的安裝非常簡(jiǎn)單,如同其他Go第三方包一樣,只需要go get
命令即可安裝
go get github.com/spf13/viper
導(dǎo)入
import "github.com/spf13/viper"
讀取配置文件單個(gè)屬性
viper.SetConfigFile("./config.yaml") viper.ReadInConfig() fmt.Println(viper.Get("我是不區(qū)分大小寫的key"))
序列化為對(duì)象
// 首先聲明一個(gè)配置映射對(duì)象 type DB struct { host string port string } func main() { viper.SetConfigName("config") viper.SetConfigType("yaml") viper.AddConfigPath(".") viper.ReadInConfig() // 讀取配置 var mysql DB viper.Unmarshal(&mysql) 將讀取到的配置序列化為對(duì)象 fmt.Println(mysql.host) fmt.Println(mysql.port) }
以上就是viper的簡(jiǎn)單使用,可以看出使用起來還是很方便簡(jiǎn)潔的。
更多語法
寫回配置文件
此外,viper還支持將配置值寫入配置文件,viper提供了四個(gè)函數(shù)將配置寫回文件。
WriteConfig
WriteConfig函數(shù)會(huì)將配置寫入預(yù)先設(shè)置好路徑的配置文件中,如果配置文件存在,則覆蓋,如果沒有,則創(chuàng)建。
SafeWriteConfig
SafeWriterConfig與WriteConfig函數(shù)唯一的不同是如果配置文件存在,則會(huì)返回一個(gè)錯(cuò)誤。
WriteConfigAs
WriteConfigAs與WriteConfig函數(shù)的不同是需要傳入配置文件保存路徑,viper會(huì)根據(jù)文件后綴判斷寫入格式。
SafeWriteConfigAs
SafeWriteConfigAs與WriteConfigAs的唯一不同是如果配置文件存在,則返回一個(gè)錯(cuò)誤。
監(jiān)聽配置文件
viper支持監(jiān)聽配置文件,并會(huì)在配置文件發(fā)生變化,重新讀取配置文件和回調(diào)函數(shù),這樣可以避免每次配置變化時(shí),都需要重啟啟動(dòng)應(yīng)用的麻煩。
// 設(shè)置監(jiān)聽回調(diào) viper.OnConfigChange(func(e fsnotify.Event) { fmt.Println("檢測(cè)到配置文件已更改:", e.Name) }) // 開啟監(jiān)聽 viper.WatchConfig()
注冊(cè)和使用別名
為某個(gè)配置key設(shè)置別名,這樣可以方便我們?cè)诓桓淖僰ey的情況下,使用別的名稱訪問該配置。
viper.Set("name", "張三") //為name設(shè)置一個(gè)username的別名 viper.RegisterAlias("username", "name") //通過username可以讀取到name的值 fmt.Println(viper.Get("username")) //修改name的配置值,username的值也發(fā)生改變 viper.Set("name", "李四") // 輸出結(jié)果為李四 fmt.Println(viper.Get("username"))
讀取環(huán)境變量
對(duì)于讀取操作系統(tǒng)環(huán)境變量,viper提供了下面五個(gè)函數(shù):
- AutomaticEnv()
- BindEnv(string...) : error
- SetEnvPrefix(string)
- SetEnvKeyReplacer(string...) *strings.Replacer
- AllowEmptyEnv(bool)
viper讀取環(huán)境變量,主要有兩種方式:
1.開啟AutomaticEnv函數(shù),可直接讀取環(huán)境變量
// 讀取不到 fmt.Println(viper.Get("path")) //開始讀取環(huán)境變量 viper.AutomaticEnv() //會(huì)從環(huán)境變量讀取到該值 fmt.Println(viper.Get("path"))
2.使用BindEnv綁定某個(gè)環(huán)境變量
//將p綁定到環(huán)境變量PATH,注意這里第二個(gè)參數(shù)是環(huán)境變量 viper.BindEnv("p", "PATH") // 通過p讀取PATH的值 fmt.Println(viper.Get("p"))
封裝使用
1.安裝庫
go get github.com/spf13/viper
2.編寫配置文件,yaml為例
新建config.yaml配置文件,內(nèi)容如下
app: # 應(yīng)用基本配置 env: local # 環(huán)境名稱 port: 8080 # 服務(wù)監(jiān)聽端口號(hào) app_name: online-practice-system # 應(yīng)用名稱 app_url: http://localhost # 應(yīng)用域名
3.定義配置映射的結(jié)構(gòu)體
這里因?yàn)榕渲糜卸鄬?,所以我們結(jié)構(gòu)體也要對(duì)應(yīng)多層,我們可以再標(biāo)簽中通過設(shè)置mapstructure屬性來設(shè)置配置的屬性名
// Configuration為管理全部配置的父結(jié)點(diǎn) type Configuration struct { App App `mapstructure:"app" yaml:"app"` } // 如果是多層配置,就需要定義多層結(jié)構(gòu)體 type App struct { // 在tag標(biāo)簽中加入yaml:"env"`,聲明配置對(duì)應(yīng)關(guān)系 Env string `mapstructure:"env" yaml:"env"` Port string `mapstructure:"port" yaml:"port"` AppName string `mapstructure:"app_name" yaml:"app_name"` AppUrl string `mapstructure:"app_url" yaml:"app_url"` }
4.編寫配置讀取初始化函數(shù)
這里我們定義了初始化函數(shù),將配置讀取到自己global包下的App.Config全局變量,這里可以自己選擇讀取那哪
package bootstrap import ( "fmt" "github.com/fsnotify/fsnotify" "github.com/spf13/viper" "online-practice-system/global" "os" ) // viper讀取配置文件初始化 func InitializeConfig() *viper.Viper { // 設(shè)置配置文件路徑 config := "config.yaml" // 生產(chǎn)環(huán)境可以通過設(shè)置環(huán)境變量來改變配置文件路徑 if configEnv := os.Getenv("VIPER_CONFIG"); configEnv != "" { config = configEnv } // 初始化 viper v := viper.New() v.SetConfigFile(config) v.SetConfigType("yaml") if err := v.ReadInConfig(); err != nil { panic(fmt.Errorf("read config failed: %s \n", err)) } // 監(jiān)聽配置文件 v.WatchConfig() v.OnConfigChange(func(in fsnotify.Event) { fmt.Println("config fileDriver changed:", in.Name) // 重載配置,這里可以進(jìn)行重啟服務(wù)器,或者其他操作 if err := v.Unmarshal(&global.App.Config); err != nil { fmt.Println(err) } }) // 將配置賦值給全局變量 if err := v.Unmarshal(&global.App.Config); err != nil { fmt.Println(err) } return v }
5.主程序啟動(dòng)前調(diào)用初始化函數(shù)
func main() { // 初始化yaml配置文件 InitializeConfig() /// }
總結(jié)
Viper是一個(gè)功能強(qiáng)大且易于使用的配置讀取庫,它可以幫助我們簡(jiǎn)化配置的讀取和管理過程,提高應(yīng)用程序的靈活性和可維護(hù)性。無論是小型項(xiàng)目還是大型應(yīng)用程序,Viper都是一個(gè)值得推薦的配置讀取解決方案。
以上就是詳解如何使用Go的Viper來解析配置信息的詳細(xì)內(nèi)容,更多關(guān)于Go Viper解析配置信息的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
go slice 擴(kuò)容實(shí)現(xiàn)原理源碼解析
這篇文章主要為大家介紹了go slice 擴(kuò)容實(shí)現(xiàn)原理源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01golang復(fù)制文件夾移動(dòng)到另一個(gè)文件夾實(shí)現(xiàn)方法詳解
這篇文章主要為大家介紹了golang復(fù)制文件夾并移動(dòng)到另一個(gè)文件夾實(shí)現(xiàn)方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07如何使用golang實(shí)現(xiàn)traceroute
這篇文章主要介紹了如何使用golang實(shí)現(xiàn)traceroute,該工具在linux環(huán)境下的命令是traceroute或者tracepath,在windows下命令是tracert,本文給大家詳細(xì)講解需要的朋友可以參考下2023-04-04golang語言http協(xié)議get拼接參數(shù)操作
這篇文章主要介紹了golang語言http協(xié)議get拼接參數(shù)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-12-12golang并發(fā)之使用sync.Pool優(yōu)化性能
在Go提供如何實(shí)現(xiàn)對(duì)象的緩存池功能,常用一種實(shí)現(xiàn)方式是sync.Pool,?其旨在緩存已分配但未使用的項(xiàng)目以供以后重用,從而減輕垃圾收集器(GC)的壓力,下面我們就來看看具體操作吧2023-10-10