Golang專案的配置管理——Viper簡易入門配置

學習先生發表於2021-12-30

Golang專案的配置管理——Viper簡易入門配置

What is Viper?

From:https://github.com/spf13/viper

Viper is a complete configuration solution for Go applications including 12-Factor apps.

(VIPER是實現遵循12-Factor的GO應用程式的完整配置解決方案)

它支援:

  • 支援 JSON/TOML/YAML/HCL/envfile/Java properties 等多種格式的配置檔案

  • 實時監控及過載配置檔案(可選)

  • 從環境變數、命令列標記、快取中讀取配置;

  • 從遠端配置系統中讀取和監聽修改,如 etcd/Consul;

  • 顯式設定鍵值。

Why Viper?

When building a modern application, you don’t want to worry about configuration file formats; you want to focus on building awesome software. Viper is here to help with that.

(構建現代應用程式時,你不想去過多關注配置檔案的格式,你想專注於建立更棒的軟體,Viper可以幫助你)

Install

go get github.com/spf13/viper

Example

初始化:

package settings

import (
   "fmt"
   "github.com/fsnotify/fsnotify"
   "github.com/spf13/viper"
)
//初始化一個viper配置
func Init() (err error) {
	//制定配置檔案的路徑
	viper.SetConfigFile("conf/config.yaml")
     // 讀取配置資訊
	err = viper.ReadInConfig()
	if err != nil {
		// 讀取配置資訊失敗
		fmt.Printf("viper.ReadInConfig()failed,err:%v\n", err)
		return
	}
	//監聽修改
	viper.WatchConfig()
	//為配置修改增加一個回撥函式
	viper.OnConfigChange(func(in fsnotify.Event) {
		fmt.Println("配置檔案修改了...")
	})
	return
}

配置檔案示例(yaml):

mysql:
  host: "127.0.0.1"
  port: 3306
  user: "root"
  password: "123456"
  dbname: "web_app"
  max_open_conns: 200
  max_idle_conns: 50
redis:
  host: "127.0.0.1"
  port: 6379
  db: 0
  password: ""
  pool_size: 100

取配置:

package mysql
//省略package
func Init() (err error) {
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True",
		viper.GetString("mysql.user"),
		viper.GetString("mysql.password"),
		viper.GetString("mysql.host"),
		viper.GetInt("mysql.port"),
		viper.GetString("mysql.dbname"),
	)
	db, err = sqlx.Connect("mysql", dsn)
	
	db.SetMaxOpenConns(viper.GetInt("mysql.max_open_conns"))
	db.SetMaxIdleConns(viper.GetInt("mysql.max_idle_conns"))
	return
}

// @version 1.0

程式內顯示宣告配置:

如果某個鍵通過viper.Set設定了值,那麼這個值的優先順序最高。如:

viper.Set("redis.port", 9000)

此時redis的介面就不是配置檔案中設定的6379,而是後面配置的9000

命令列選項:

func init() {
  pflag.Int("redis.port", 9001, "Redis port to connect")

  // 繫結命令列
  viper.BindPFlags(pflag.CommandLine)
}

程式碼執行時傳入引數:$ ./main.exe --redis.port 9001

此時程式配置的redis埠為:9001。

如果我們不傳入引數直接執行$ ./main.exe

此時程式配置的redis埠為配置檔案中的6379(沒有在程式中顯示宣告配置時viper.Set("redis.port", 9000))。

環境變數:

func init() {
  // 繫結環境變數
  viper.AutomaticEnv()
}

在沒有於前面的方法中取得配置的情況下,則會繫結環境變數。

也可以指定繫結對應的環境變數:

func init() {
  // 繫結環境變數
  viper.BindEnv("redis.port")
  viper.BindEnv("go.path", "GOPATH")
}

BindEnv()如果只傳入一個引數,則這個引數既表示鍵名,又表示環境變數名。如果傳入兩個引數,則第一個參數列示鍵名,第二個參數列示環境變數名。

也可以通過viper.SetEnvPrefix()設定環境變數字首,設定後前面的方法會為傳入的值加上變數後再去查詢環境變數。

  • 預設值可以呼叫viper.SetDefault設定。

總結優先順序:

呼叫Set顯式設定的>命令列選項傳入的>環境變數>配置檔案>預設值;

總結

初始化:

  1. 設定配置檔案路徑viper.SetConfigFile()
  2. 讀取配置viper.ReadInConfig()
  3. 監聽修改viper.WatchConfig()
  4. 設定修改後回撥viper.OnConfigChange(func())

呼叫:

​ 取配置viper.Get*()

設定優先順序:

宣告呼叫Set顯式設定的>命令列選項傳入的>環境變數>配置檔案>預設值;

我的個人站:mrxuexi.com

頭像

相關文章