バイパーとは#
Viperは、Go言語アプリケーションが構成情報を処理するのを容易にするライブラリです。複数の形式の構成を処理できます。サポートする機能:
- デフォルトに設定
- JSON、TOML、YAML、HCL、およびJavaプロパティファイルから構成データを読み取ります
- 構成ファイルの変更を監視し、構成ファイルを再読み取りできます
- 環境変数から構成データを読み取る
- リモート構成システムからデータを読み取り、それらを監視します(etcd、Consulなど)
- コマンドパラメータから設定を読み取ります
- バッファから読み取る
- 関数を呼び出して構成情報を設定します
Viperを使用する理由#
最新のアプリケーションを構築する場合、構成ファイルの形式について心配する必要はありません。優れたソフトウェアの構築に集中できます。
Viperは次のことを実行できます。
- JSON、TOML、YAML、HCL、またはJavaプロパティ形式の構成ファイルをロードして解析します
- さまざまな構成アイテムのデフォルト値を設定できます
- コマンドラインで構成項目を指定して、構成値を上書きできます
- 既存のコードを破壊することなくパラメータの名前変更を実現できるエイリアスシステムを提供します
- ユーザーが提供するコマンドラインパラメータまたは設定ファイルとデフォルトの違いを簡単に区別できます
Viperは、次のように、構成情報の優先順位を高いものから低いものへと読み取ります。
- Set関数を明示的に呼び出す
- コマンドラインパラメータ
- 環境変数
- 構成ファイル
- キー/値ストレージシステム
- デフォルト
Viper構成アイテムのキーでは、大文字と小文字は区別されません。
プロジェクトアドレス:https://github.com/spf13/viper
#を使用
デフォルト値は必要ありません。構成ファイル、環境変数、リモート構成システム、コマンドラインパラメーター、および集合関数が指定されていない場合、デフォルト値が機能します。
viper.SetDefault("name", "xiaoming")
viper.SetDefault("age", "12")
viper.SetDefault("notifyList", []string{"xiaohong","xiaoli","xiaowang"})
Viperは、JSON、TOML、YAML、HCL、およびJavaプロパティファイルをサポートしています。
Viperは複数のパスを検索できますが、現在、単一のViperインスタンスは単一の構成ファイルのみをサポートしています。
Viperは、デフォルトではパスを検索しません。
以下は、Viperを使用して構成ファイルを検索および読み取る方法の例です。
パスは必須ではありませんが、構成ファイルを見つけるために少なくとも1つのパスを指定することをお勧めします。
viper.SetConfigName("dbConfig") // 设置配置文件名 (不带后缀)
viper.AddConfigPath("/workspace/appName/") // 第一个搜索路径
viper.AddConfigPath("/workspace/appName1") // 可以多次调用添加路径
viper.AddConfigPath(".") // 比如添加当前目录
err := viper.ReadInConfig() // 搜索路径,并读取配置数据
if err != nil {
panic(fmt.Errorf("Fatal error config file: %s \n", err))
}
Viperは、アプリケーションが実行時に構成ファイルを読み取ることができるようにすることをサポートしています。
viperインスタンスのWatchConfig関数を呼び出すだけで、変更を通知するコールバック関数を指定することもできます。
viper.WatchConfig()
viper.OnConfigChange(func(e fsnotify.Event) {
fmt.Println("Config file changed:", e.Name)
})
Viperは、ファイル、環境変数、コマンドラインパラメーター、リモートK / Vストレージシステムなどの多くの構成ソースを事前に定義します。独自の構成ソースを実装して、それをviperに提供することもできます。
現在、次のyamlファイルがあります。
userName: "xiaoming"
address: "广州市XXX"
sex: 1
company:
name: "xxx"
employeeId: 1000
department:
- "技术部"
ファイルを読み取るためのコードは次のとおりです。
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()
//设置读取的配置文件名
v.SetConfigName("userInfo")
//windows环境下为%GOPATH,linux环境下为$GOPATH
v.AddConfigPath("/Users/yangyue/workspace/go/src/webDemo/")
//设置配置文件类型
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)
}
上記のコードは、構成ファイルを取得するために2つの方法を使用します。1つはキーと値に直接解析され、2つ目は手動でStructに逆シリアル化できることです。
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"))
}
コマンドラインは上記のプログラムを実行します。
# go run test.go --ip=192.168.7.3 --port=3306
出力がカスタムパラメータであることがわかります。
通常os
、次のようなパッケージを使用して環境変数を取得します。
getenv := os.Getenv("JAVA_HOME")
fmt.Print(getenv)
Viperは次の方法も提供します。
//表示 先预加载匹配的环境变量
viper.AutomaticEnv()
//读取已经加载到default中的环境变量
if env := viper.Get("JAVA_HOME"); env == nil {
println("error!")
} else {
fmt.Printf("%#v\n", env)
}
環境変数を取得することで、複数の環境パラメータ構成を考えることができますか?オンライン環境の場合、開発環境はパラメーターをそれぞれ異なるymlにロードします。
func initConfig() (err error) {
env := os.Getenv("GO_ENV")
viper.SetConfigName(env)
viper.AddConfigPath("./configs")
viper.SetConfigType("yml")
err = viper.ReadInConfig()
return
}
オンライン環境であろうとテスト環境であろうと、公開されていて変更されていないパラメーターがいくつかある必要があります。パラメーターのこの部分を個別の構成ファイルとして抽出できますか?したがって、この構成ファイルは2つの部分に分けることができます。
"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中的配置全部以默认配置写入
for k, v := range configs {
viper.SetDefault(k, v)
}
env := os.Getenv("GO_ENV")
// 根据配置的env读取相应的配置信息
if env != "" {
envConfig, _ := box.Find(env + ".yml")
viper.SetConfigType(configType)
err = viper.ReadConfig(bytes.NewReader(envConfig))
if err != nil {
return
}
}
return
}
最初にdefault.ymlのパラメーターを読み取り、それらをdefaultに書き込みます。次に、環境変数に従って、さまざまな環境のパラメーターを読み取ります。
ここではpackrパッケージを使用します。packrパッケージの機能は、静的リソースをアプリケーションにパックすることです。