本節核心內容
- 介紹 Viper
- 介紹 如何配置 Viper 並讀取其配置,以及配置的高級用法
本小節視頻教程和代碼:百度網盤
可先下載視頻和源碼到本地,邊看視頻邊結合源碼理解后續內容,邊學邊練。
附帶golang.org包的下載地址
Viper 簡介
Viper 是國外大神 spf13 編寫的開源配置解決方案,具有如下特性:
- 設置默認值
- 可以讀取如下格式的配置文件:JSON、TOML、YAML、HCL
- 監控配置文件改動,並熱加載配置文件
- 從環境變量讀取配置
- 從遠程配置中心讀取配置(etcd/consul),並監控變動
- 從命令行 flag 讀取配置
- 從緩存中讀取配置
- 支持直接設置配置項的值
Viper 配置讀取順序:
viper.Set()
所設置的值- 命令行 flag
- 環境變量
- 配置文件
- 配置中心:etcd/consul
- 默認值
從上面這些特性來看,Viper 毫無疑問是非常強大的,而且 Viper 用起來也很方便,在初始化配置文件后,讀取配置只需要調用 viper.GetString()
、viper.GetInt()
和 viper.GetBool()
等函數即可。
Viper 也可以非常方便地讀取多個層級的配置,比如這樣一個 YAML 格式的配置:
common:
database:
name: test
host: 127.0.0.1
如果要讀取 host 配置,執行 viper.GetString("common.database.host")
即可。
apiserver 采用 YAML 格式的配置文件,采用 YAML 格式,是因為 YAML 表達的格式更豐富,可讀性更強。
獲取viper.Set()的值
func main() {
//獲取viper.Set()
viper.Set("name","jeck")
fmt.Println(viper.GetString("name"))
}
使用viper獲取Set()函數添加的值很簡單,直接再Get出來就好。
讀取配置文件
func main() {
viper.AddConfigPath("conf")
viper.SetConfigName("config")
viper.ReadInConfig()
fmt.Println(viper.GetString("common.database.host"))
}
代碼解析:
viper.AddConfigPath("conf")
用來指定yaml配置文件的路徑viper.SetConfigName("config")
用來指定配置文件的名稱viper.ReadInConfig()
是解析配置文件的函數,如果配置文件的路徑錯誤獲名稱錯誤則解析失敗,會報錯誤viper.GetString("db.uri")
是用來從配置文件中根據層級關系來獲取數據- 最后,通過fmt.Println()對數據結果進行輸出
代碼優化
使用viper讀取配置文件的代碼雖然很簡單,但如果我們在開發中每次讀取配置文件時都這樣一遍遍寫的話,那代碼量就太大了,因此我們可以通過抽取的方式對代碼進行優化,這樣只需要在關鍵地方調用就可以了
main
函數通過 config.Init
函數來解析並 watch 配置文件(函數路徑:config/config.go
),config.go 源碼為:
package config
import "github.com/spf13/viper"
//Init讀取初始化配置文件
func Init() error {
viper.AddConfigPath("conf")
viper.SetConfigName("config")
err := viper.ReadInConfig()
if err != nil {
return err
}
return nil
}
通過將代碼抽離出來,這樣我們就只需要在讀取配置前調用一下config.Init()
方法就可以了。
Viper 高級用法
從環境變量讀取配置
Viper 可以從環境變量讀取配置,這是個非常有用的功能。現在越來越多的程序是運行在 Kubernetes 容器集群中的,在 API 服務器遷移到容器集群時,可以直接通過 Kubernetes 來設置環境變量,然后程序讀取設置的環境變量來配置 API 服務器。讀者不需要了解如何通過 Kubernetes 設置環境變量,只需要知道 Viper 可以直接讀取環境變量即可。
func main() {
viper.AutomaticEnv()
if env := viper.Get("GOROOT"); env == nil {
println("error!")
} else {
fmt.Printf("%#v\n", env)
}
}
代碼解析:
viper.AutomaticEnv()
用來讀取匹配的環境變量viper.Get("GOROOT")
獲取GOPOOT的環境變量,當獲取不到時,env
為空,我們通過println()
函數來輸出格式后的error
fmt.Printf("%#v\n", env)
輸出結果
小結
本小節展示了如何用強大的配置管理工具 Viper 來解析配置文件並讀取配置,還演示了 Viper 的高級用法。