1. 程式人生 > 實用技巧 >golang 配置檔案解析神器--viper

golang 配置檔案解析神器--viper

專案地址:https://github.com/spf13/viper

安裝方式:go get github.com/spf13/viper

簡介

viper是一個十分強大的配置檔案解析工具,具有以下特點

  • 設定預設值
  • 支援的檔案包括JSON, TOML, YAML, HCL, envfile 和 Java properties 配置檔案
  • 實時監聽和重新讀取配置檔案
  • 從環境變數中讀取
  • 從遠端配置系統(etcd或Consul)中讀取,並監聽更改
  • 從命令列讀取
  • 從緩衝讀取
  • 設定顯示值

另外需要注意的是,viper對配置中的key是大小寫不敏感的

下面我以YAML格式的配置檔案為例,介紹viper的用法,其他跟多的用法請見

官網

示例配置檔案

一個好的專案應該把配置檔案分成兩份,一份存放不敏感資訊(比如專案執行埠),一份存放敏感資訊(比如資料庫密碼),下面兩個配置檔案用作舉例

public config config/config/config.yaml

TimeStamp: "2018-07-16 10:23:19"
Username: "horika"
BasicInfo:
   RealName: "Harry"
   Age: "18"
   Language:
   - "Golang"
   - "Python"
   - "C++"
   Married: false

Hobby:
  Sport:
  - "Lure"
  - "pingpong"
  Music:
  - "Bohemian Rhapsody"
  LuckyNumber: 22

secret config config/secret/secret.yaml

redis:
  admin:
    addr: "127.0.0.1:6379"
    password: ""
    db: 0
mysql:
  driver: "mysql"
  uri:
    "root:123456@tcp(localhost:3306)/user?charset=utf8&parseTime=True&loc=Local&multiStatements=true"
jwt:
  secret: "horika@^-^@kainhuck"

告訴viper你要解析的配置檔案是什麼

示例程式碼

var config *viper.Viper

// Init 初始化配置檔案解析
func Init(){
	config = viper.New()
	// 設定 public 配置檔名
	config.SetConfigName("config")
	// 設定 public 配置檔案型別
	config.SetConfigType("yaml")
	// 設定配置檔案存放的目錄
	config.AddConfigPath("./config/config")
	// 讀取該配置檔案
	config.ReadInConfig()

	// 解析 secret config
	config.SetConfigName("secret")
	config.SetConfigType("yaml")
	config.AddConfigPath("./config/secret")
	config.MergeInConfig()
}

說明

  • SetConfigName 指定配置檔名,不需要加字尾
  • SetConfigType 指定配置檔案型別,可以省略,viper會自動識別
  • AddConfigPath 新增配置檔案所在目錄,可以多個,告訴viper區哪裡尋找配置檔案
  • ReadInConfig 從前面告知的配置中載入配置檔案
  • MergeInConfig 從前面告知的配置中載入配置檔案併合併到之前

上面演示的只是一種讀取方式,viper還有其他的讀取方式

var config *viper.Viper

// Init 初始化配置檔案解析
func Init(){
	config = viper.New()
	// 設定 public 配置檔名
	config.SetConfigFile("./config/config/config.yaml")
	// 讀取該配置檔案
	config.ReadInConfig()

	// 解析 secret config
	config.SetConfigFile("./config/secret/secret.yaml")
	config.MergeInConfig()
}

說明

  • SetConfigFile 指定配置檔案的全路徑

從IO流中讀取配置檔案

var config *viper.Viper

// Init 初始化配置檔案解析
func Init() {
	config = viper.New()
	f, _ := os.Open("./config/config/config.yaml")
	defer f.Close()
	config.SetConfigType("yaml")
	config.ReadConfig(f)

	s, _ := os.Open("./config/secret/secret.yaml")
	defer s.Close()
	config.SetConfigType("yaml")
	config.MergeConfig(s)
}

說明

  • ReadConfig 讀取io流,注意和ReadInConfig區分
  • SetConfigType 從流中讀取需要指定檔案型別

讀取配置檔案

viper讀取配置檔案就是各種Get

  • Get 自動判斷型別
  • GetTime 獲取時間型別
  • GetString 獲取字串型別
  • GetBool 獲取bool型別
  • GetInt 獲取int型別
  • GetStringMap 獲取map型別
  • ...

示例

fmt.Println(config.Get("username"))
fmt.Println(config.Get("mysql"))
fmt.Println(config.GetTime("timestamp"))

序列化

viper作為一個優秀的配置檔案解析工具,他支援將配置資訊序列化為結構體物件

package main

import (
	"fmt"

	"github.com/spf13/viper"
)

var config *viper.Viper
var AllConfig TotalConfig

// Init 初始化配置檔案解析
func Init() {
	config = viper.New()
	config.SetConfigFile("./config/config/config.yaml")
	config.ReadInConfig()
	config.SetConfigFile("./config/secret/secret.yaml")
	config.MergeInConfig()
	config.Unmarshal(&AllConfig)
}

type basicinfo struct {
	RealName string
	Age      int
	Language []string
	Married  bool
}

type hobby struct {
	Sport       []string
	Music       []string
	LuckyNumber int
}

type admin struct {
	Addr      string
	paswsword string
	db        int
}

type redis struct {
	Admin admin
}

type mysql struct {
	Driver string
	Uri    string
}

type jwt struct {
	Secret string
}

type TotalConfig struct {
	TimeStamp string
	Username  string
	BasicInfo basicinfo
	Hobby     hobby
	Redis     redis
	Mysql     mysql
	Jwt       jwt
}

func main() {
	Init()
	fmt.Println(AllConfig.BasicInfo.Married)
	fmt.Println(AllConfig.Jwt.Secret)
}