文章介紹
本文我們將來介紹一下如何從第三方包viper來獲取配置檔案的配置資訊,以及開發模式下的配置和上線產品如何使用進行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)
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結