1. 程式人生 > 其它 >golang中的配置管理庫viper

golang中的配置管理庫viper

viper簡介

Viper是適用於Go應用程式的完整配置解決方案。它旨在在應用程式中工作,並且可以處理所有型別的配置需求和格式。它支援:

設定預設值
從JSON,TOML,YAML,HCL,envfile和Java屬性配置檔案中讀取
實時觀看和重新讀取配置檔案(可選)
從環境變數中讀取
從遠端配置系統(etcd或Consul)中讀取,並觀察更改
從命令列標誌讀取
從緩衝區讀取
設定顯式值
可以將Viper視為滿足您所有應用程式配置需求的登錄檔。

載入配置優先順序

Viper會按照下面的優先順序。每個專案的優先順序都高於它下面的專案:

顯示呼叫Set設定值
命令列引數(flag)
環境變數
配置檔案
key/value儲存
預設值

目錄結構

config.yaml

db:
  username: mayanan
  password: 123456789
  host: 123.123.12.123
  port: 33066
  database: docker01
v: 88.88  # 將會覆蓋: v.SetDefault("V", "1.11")  // 建立預設值
version: 99.99

config.go

package config

import (
	"fmt"
	"github.com/fsnotify/fsnotify"
	"github.com/spf13/viper"
	"os"
)

func LoadConfigFromYaml() (v *viper.Viper, err error) {
	v = viper.New()
	v.SetConfigName("config.yaml")
	v.AddConfigPath("./config/")
	v.SetConfigType("yaml")
	v.Set("version", "2.22")  // 顯示呼叫Set設定值
	v.SetDefault("V", "1.11")  // 建立預設值

	// viper從環境變數讀取
	v.SetEnvPrefix("spf")
	v.BindEnv("id")
	os.Setenv("spf_id", "111")

	if err = v.ReadInConfig(); err != nil {
		if _, ok := err.(viper.ConfigFileNotFoundError); ok {
			// Config file not found; ignore error if desired
			fmt.Println("Config file not found; ignore error if desired")
		} else {
			// Config file was found but another error was produced
			fmt.Println("Config file was found but another error was produced")
		}
	}

	// 監控配置和重新獲取配置
	v.WatchConfig()

	v.OnConfigChange(func(e fsnotify.Event) {
		fmt.Println("Config file changed:", e.Name)
	})
	return v, err
}

main.go

package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"viperTest/config"
)

func main() {
	router := gin.Default()
	v, _ := config.LoadConfigFromYaml()
	router.GET("/", func(context *gin.Context) {
		context.JSON(200, gin.H{
			"config": v.AllSettings(),
		})
		fmt.Println(v.GetString("db.password"), v.Get("id"))  // 獲取單個配置屬性
	})
	router.Run("127.0.0.1:8899")
}

獲取值

在Viper中,根據值的型別,有幾種獲取值的方法。存在以下功能和方法:

Get(key string) : interface{}
GetBool(key string) : bool
GetFloat64(key string) : float64
GetInt(key string) : int
GetIntSlice(key string) : []int
GetString(key string) : string
GetStringMap(key string) : map[string]interface{}
GetStringMapString(key string) : map[string]string
GetStringSlice(key string) : []string
GetTime(key string) : time.Time
GetDuration(key string) : time.Duration
IsSet(key string) : bool
AllSettings() : map[string]interface{}

postman請求介面

http://127.0.0.1:8899
響應:

{
    "config": {
        "db": {
            "database": "docker01",
            "host": "123.123.12.123",
            "password": 123456,
            "port": 33066,
            "username": "mayanan"
        },
        "v": "1.11",
        "version": "2.22"
    }
}

此時把config.yaml中的內容改一下,再次請求介面,響應發生變化,根本不用重啟我們的應用程式,非常的友好

寫入配置檔案

從配置檔案中讀取配置檔案是有用的,但是有時你想要儲存在執行時所做的所有修改。為此,可以使用下面一組命令,每個命令都有自己的用途:

WriteConfig - 將當前的viper配置寫入預定義的路徑並覆蓋(如果存在的話)。如果沒有預定義的路徑,則報錯。
SafeWriteConfig - 將當前的viper配置寫入預定義的路徑。如果沒有預定義的路徑,則報錯。如果存在,將不會覆蓋當前的配置檔案。
WriteConfigAs - 將當前的viper配置寫入給定的檔案路徑。將覆蓋給定的檔案(如果它存在的話)。
SafeWriteConfigAs - 將當前的viper配置寫入給定的檔案路徑。不會覆蓋給定的檔案(如果它存在的話)。
根據經驗,標記為safe的所有方法都不會覆蓋任何檔案,而是直接建立(如果不存在),而預設行為是建立或截斷。
小示例:

viper.WriteConfig() // 將當前配置寫入“viper.AddConfigPath()”和“viper.SetConfigName”設定的預定義路徑
viper.SafeWriteConfig()
viper.WriteConfigAs("/path/to/my/.config")
viper.SafeWriteConfigAs("/path/to/my/.config") // 因為該配置檔案寫入過,所以會報錯
viper.SafeWriteConfigAs("/path/to/my/.other_config")

viper中使用環境變數

Viper 完全支援環境變數。這使得12因素的應用程式開箱即用。有五種方法可以幫助與 ENV 合作:

AutomaticEnv()  // 可以通過v讀取:v.Get("id")
BindEnv(string...) : error  // 繫結到viper中,既可以通過v讀取,也可以通過v拿到配置
SetEnvPrefix(string)
SetEnvKeyReplacer(string...) *strings.Replacer
AllowEmptyEnv(bool)

viper簡介
github.com/spf13/viper