Go语言学习笔记——配置管理库viper

文章目录

  • Golang配置管理库viper
    • Viper 是什么?
    • 为什么要使用 Viper?
    • 安装viper
    • 常见用法快速入门
      • 读取ini配置文件
      • 读取yaml配置文件
    • 将配置注册到 viper
      • 创建默认值
      • 从配置文件读取值
      • 将 viper值保存到配置文件
      • 监测并热加载配置文件
      • 从 io.Reader 读取配置
    • 从 viper 读取配置
      • 读取单个值方法
      • 读取嵌套的配置


Golang配置管理库viper

viper是一个golang配置管理库,很多项目都使用viper来构建,例如:docker、Hugo等等

Viper 是什么?

viper 是以个完善的go语言配置包.开发它的目的是来处理各种格式的配置文件信息.

viper 支持:

  • 设置默认配置
  • 支持读取JSON TOML YAML HCL、envfile和Java属性配置文件
  • (可选)监听配置文件变化,实时读取读取配置文件内容
  • 读取环境变量值
  • 读取远程配置系统(etcd Consul)和监控配置变化
  • 读取命令行flag值
  • 读取buffer值
  • 读取确切值

为什么要使用 Viper?

当你创建app的时候需要关注怎么创建完美的app,而不需要关注怎么写配置文件.

viper 能够帮你做这些事情

  • 找到和反序列化JSON TOML YAML HCL JAVA配置文件
  • 提供一个配置文件默认值和可选值的机制
  • 提供重写配置值和Flag的可选值
  • 提供系统的参数别名,解决对以有代码的侵入
  • 轻松的辨别出用户输入值还是配置文件值

安装viper

go get github.com/spf13/viper

常见用法快速入门

读取ini配置文件

ini配置文件:

[db]
username=admin
password=123
driver=mysql
port=3306

[web]
port=8080

读取:

package main

import (
	"fmt"

	"github.com/spf13/viper"
)

func ReadIni() {
	v := viper.New()
	v.AddConfigPath("./conf") // 路径
	v.SetConfigName("config") // 名称
	v.SetConfigType("ini")    // 类型

	err := v.ReadInConfig() // 读取配置
	if err != nil {
		panic(err)
	}

	s := v.GetString("db.username")
	fmt.Printf("s: %v\n", s)

	i := v.GetInt("web.port")
	fmt.Printf("i: %v\n", i)
}

func main() {
	ReadIni()
}

运行结果:

[Running] go run "e:\golang开发学习\go_pro\main.go"
s: admin
i: 8080

[Done] exited with code=0 in 2.061 seconds

读取yaml配置文件

yaml配置文件:

db:
 username: admin
 password: 123
 driver: mysql
 port: 3306
web:
 port: 8080

读取:

package main

import (
	"fmt"

	"github.com/spf13/viper"
)

func ReadYaml() {
	v := viper.New()
	v.AddConfigPath("./conf") // 路径
	v.SetConfigName("config") // 名称
	v.SetConfigType("yaml")   // 类型

	err := v.ReadInConfig() // 读取配置
	if err != nil {
		panic(err)
	}

	s := v.GetString("db.username")
	fmt.Printf("s: %v\n", s)

	i := v.GetInt("web.port")
	fmt.Printf("i: %v\n", i)
}

func main() {
	ReadYaml()
}

运行结果:

[Running] go run "e:\golang开发学习\go_pro\main.go"
s: admin
i: 8080

[Done] exited with code=0 in 1.817 seconds

将配置注册到 viper

创建默认值

 viper.SetDefault("Name", "wohu")
 viper.SetDefault("Gender", "male")
 viper.SetDefault("City", map[string]string{"country": "China", "Province": "Beijing"})

从配置文件读取值

viper默认不配置文件的搜索路径,将配置文件路径的搜索决定权放在用户程序中。

viper.SetConfigName("config") // 配置文件名字,注意没有扩展名
viper.SetConfigType("yaml") // 如果配置文件的名称中没有包含扩展名,那么该字段是必需的
viper.AddConfigPath("/etc/appname/")   // 配置文件的路径
viper.AddConfigPath("$HOME/.appname")  // 多次调用添加多个配置文件的路径
viper.AddConfigPath(".")               // 在当前工作目录寻找配置文件
err := viper.ReadInConfig() // 查找并读取配置文件
if err != nil { 
	panic(fmt.Errorf("Fatal error config file: %w \n", err))
}

将 viper值保存到配置文件

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支持应用程序在运行中实时读取配置文件的能力。确保在调用 WatchConfig()之前添加所有的configPaths。

viper.WatchConfig()
viper.OnConfigChange(func(e fsnotify.Event) {
	fmt.Println("Config file changed:", e.Name)
})

从 io.Reader 读取配置

viper.SetConfigType("yaml") // or viper.SetConfigType("YAML")
 
// any approach to require this configuration into your program.
var yamlExample = []byte(`
Hacker: true
name: steve
hobbies:
- skateboarding
- snowboarding
- go
clothing:
  jacket: leather
  trousers: denim
age: 35
eyes : brown
beard: true
`)
 
viper.ReadConfig(bytes.NewBuffer(yamlExample))
 
viper.Get("name") // this would be "steve"

从 viper 读取配置

读取单个值方法

在 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{}

注意:如果没有找到,每个 Get函数将返回一个 0 值。为了检查一个给定的键是否存在,已经提供了 IsSet()方法。

读取嵌套的配置

{
    "host": {
        "address": "localhost",
        "port": 5799
    },
    "datastore": {
        "metric": {
            "host": "127.0.0.1",
            "port": 3099
        },
        "warehouse": {
            "host": "198.0.0.1",
            "port": 2112
        }
    }
}

viper可以通过传递一个以 .为界的键值路径来访问一个嵌套字段。

GetString("datastore.metric.host") // (returns "127.0.0.1")

viper可以通过使用路径中的数字来访问数组索引,例如:

{
    "host": {
        "address": "localhost",
        "ports": [
            5799,
            6029
        ]
    },
    "datastore": {
        "metric": {
            "host": "127.0.0.1",
            "port": 3099
        },
        "warehouse": {
            "host": "198.0.0.1",
            "port": 2112
        }
    }
}
 
GetInt("host.ports.1") // returns 6029

如果存在一个与划定的键路径相匹配的键,其值将被返回。例如:

{
    "datastore.metric.host": "0.0.0.0",
    "host": {
        "address": "localhost",
        "port": 5799
    },
    "datastore": {
        "metric": {
            "host": "127.0.0.1",
            "port": 3099
        },
        "warehouse": {
            "host": "198.0.0.1",
            "port": 2112
        }
    }
}
 
GetString("datastore.metric.host") // returns "0.0.0.0"

你可能感兴趣的:(Go精进,学习,golang)