七叶笔记 » golang编程 » Golang配置文件管理神器Viper(上)

Golang配置文件管理神器Viper(上)

配置文件管理是我们在开发过程中必须重视的一个环节。今天小编给大家推荐一个功能丰富的管理配置文件的类库 viper(蝮蛇),这个名字听上去就很凶,该类库的作者还有一个类库叫Cobra(眼镜蛇)。这两个包可以独立使用,也可以组合使用。当然本文的重点是viper,接下来赶紧跟随小编的脚步来体验一下这个强大的类库吧。

特性

  • 支持设置默认值
  • 支持读取JSON TOML YAML HCL 和Java属性配置文件.(官方说可以解析所有类型的配置文件 can handle all types of configuration needs and formats.)
  • 可以监控配置文件的变动,并实时读取配置文件内容
  • 支持读取环境变量
  • 支持从远端配置系统读取信息(如:etcd、consul),并且可以监听器变化
  • 支持读取命令行的flag标识作为配置信息
  • 可以从缓冲区中读取
  • 支持设置显示的值

配置加载顺序

  1. 设置显示调用(explicit call to Set)
  2. 命令行标志(flag)
  3. 环境变量(env)
  4. 配置文件(config)
  5. 远程键/值存储(key/value store)
  6. 默认值(default)

基本用法

我写了一个简单的demo,目录结构如下

 ├── config
│   └── env.yml
├── go.mod
├── go.sum
└── main.go  

一、从单个配置文件读取配置

 package main

import (
	"fmt"

	"github.com/spf13/viper"
)

// 定义Mysql配置对应的结构体
type MysqlConf struct {
	Host            string
	Port            int
	Username        string
	Password        string
	Database        string
	Charset         string
	DBPrefix        string
	Collection      string
	ConnTimeout     int
	MaxOpenConns    int
	MaxIdleConns    int
	ConnMaxLifetime int
	LogMode         bool
}

func main() {
	// 设置配置文件的路径
	viper.AddConfigPath("./config")
	// 设置配置文件名称
	viper.SetConfigName("env.yml")
  // 以上2步可用  	viper.SetConfigFile("./config/env.yml")代替,直接指定文件的相对路径
	// 设置配置文件类型
	viper.SetConfigType("yaml")
	// 加载配置文件内容
	if err := viper.ReadInConfig(); err != nil {
		if _, ok := err.(viper.ConfigFileNotFoundError); ok {
			// 配置文件未找到
			panic("配置文件未找到")
		} else {
			// Config file was found but another error was produced
			panic(fmt.Errorf("读取配置文件失败: %s \n", err.Error()))
		}

	}

	// 读取文件配置项
	domain := viper.GetString("Domain")       // 读取Domain节点
	serverPort := viper.GetInt("ServerPort")  // 读取ServerPort节点并且返回值未int类型
	mysqlPort := viper.GetInt("MySQL.Port")   // 读取MySQL节点下的Port节点 . 符号隔开层级
  fmt.Println(domain, serverPort, mysqlPort)


  // 将整个MySQL节点下的内容读取到结构体中
	var myCnf MysqlConf
	if err := viper.UnmarshalKey("MySQL", &myCnf); err != nil {
		fmt.Println("Read MySQL config error" + err.Error())
	}
	fmt.Printf("%+v \n", myCnf)
}  

读取文件内容的方法如下

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

二、从多配置文件读取

我现在在config目录下加了一个redis.yml配置文件,内容如下

 Host: "127.0.0.1"
Port: 6379
Password: ""
Database: 0 # 默认:0
ConnTimeout: 10 # 连接超时时间「单位:秒」
ReadTimeout: 10 # 读取超时时间「单位:秒」
WriteTimeout: 10 # 写入超时时间「单位:秒」
MaxActiveConn: 20 # 最大活跃连接数
MaxIdleConn: 10 # 最大空闲连接数
IdleTimeout: 3600 # 连接空闲的超时时间「单位:秒;0:不限」
MaxConnLifetime: 0 # 连接能够被复用的最大生命周期「单位:秒;0:不限」
TestOnBorrow: 60 # 连接健康检查周期「单位:秒」
PoolWait: false # 连接池无连接时,是否等待连接回池  

分开读取配置信息

 	// 读取env.yml的配置信息
	envYaml := viper.New()
	envYaml.SetConfigFile("./config/env.yml")
	envYaml.SetConfigType("yaml")
	if err := envYaml.ReadInConfig(); err != nil {
		panic("Read env config file error:" + err.Error())
	}
	fmt.Println(envYaml.GetString("Domain"))    // 127.0.0.1

	// 读取redis.yml的配置信息
	redisYaml := viper.New()
	redisYaml.SetConfigFile("./config/redis.yml")
	redisYaml.SetConfigType("yaml")
	if err := redisYaml.ReadInConfig(); err != nil {
		panic("Read env config file error:" + err.Error())
	}
	fmt.Println(redisYaml.GetInt("Port"))      // 6379  

小编会在 一文中继续讲解如何使用viper将配置写入文件以及配置文件的监听

相关文章