golang viper配置文件管理

Viper是适用于Go应用程序的完整配置解决方案。它被设计用于在应用程序中工作,并且可以处理所有类型的配置需求和格式。它支持以下特性:

(1)设置默认值

(2)从JSON、TOML、YAML(YAML教程)、HCL、envfile和Java properties格式的配置文件读取配置信息

(3) 实时监控和重新读取配置文件(可选)

(4)从环境变量中读取

(5)从远程配置系统(etcd或Consul)读取并监控配置变化

(6)从命令行参数读取配置

(7)从buffer读取配置

(8)显式配置值

Viper安装

cpp 复制代码
go get github.com/spf13/viper
简单使用

目录结构

config.yaml

cpp 复制代码
name: ' user'

main.go

cpp 复制代码
package main

import (
	"fmt"

	"github.com/spf13/viper"
)

func main() {
	v := viper.New()
	v.SetConfigFile("config.yaml")
	if err := v.ReadInConfig(); err != nil {
		panic(err)
	}
	fmt.Println(v.Get("name"))
}

cd到viper_test目录运行(go build main.go)

将配置文件映射成struct

cpp 复制代码
package main

import (
	"fmt"

	"github.com/spf13/viper"
)

type ServerConfig struct {
	ServerName string `mapstructure:"name"`
}

func main() {
	v := viper.New()
	v.SetConfigFile("config.yaml")
	if err := v.ReadInConfig(); err != nil {
		panic(err)
	}
	serverConfig := ServerConfig{}
	if err := v.Unmarshal(&serverConfig); err != nil {
		panic(err)
	}
	fmt.Println(serverConfig)
	fmt.Println(v.Get("name"))
}
嵌套映射

config.yaml

cpp 复制代码
name: ' user'
mysql:
  host: '127.0.0.1'
  port: 3306

main.go

cpp 复制代码
package main

import (
	"fmt"

	"github.com/spf13/viper"
)

type MysqlConfig struct {
	Host string `mapstruct:"host"`
	Port int    `mapstruct:"port"`
}
type ServerConfig struct {
	ServerName string      `mapstructure:"name"`
	MysqlInfo  MysqlConfig `mapstructure:"mysql"`
}

func main() {
	v := viper.New()
	v.SetConfigFile("config.yaml")
	if err := v.ReadInConfig(); err != nil {
		panic(err)
	}
	serverConfig := ServerConfig{}
	if err := v.Unmarshal(&serverConfig); err != nil {
		panic(err)
	}
	fmt.Println(serverConfig)
	fmt.Println(v.Get("name"))
}
开发环境和生产环境隔离配置

设置环境变量

cpp 复制代码
vim  ~/.zshrc
cpp 复制代码
export VIPER_DEBUG=true
cpp 复制代码
source ~/.zshrc

config-pro.yaml是生产环境的路径,config-debug.yaml是开发环境的路径

cpp 复制代码
package main

import (
	"fmt"

	"github.com/spf13/viper"
)

type ServerConfig struct {
	ServerName string `mapstructure:"name"`
}

func GetEnvInfo(env string) bool {
	viper.AutomaticEnv()
	return viper.GetBool(env)
}
func main() {
	debug := GetEnvInfo("VIPER_DEBUG")
	configFileName := "config-pro.yaml"
	if debug {
		configFileName = "config-debug.yaml"
	}
	v := viper.New()
	v.SetConfigFile(configFileName)
	if err := v.ReadInConfig(); err != nil {
		panic(err)
	}
	serverConfig := ServerConfig{}
	if err := v.Unmarshal(&serverConfig); err != nil {
		panic(err)
	}
	fmt.Println(serverConfig)
	fmt.Println(v.Get("name"))
}
动态监听配置文件变化

运行完之后需要更改yaml文件并保存

cpp 复制代码
package main

import (
	"fmt"
	"time"

	"github.com/fsnotify/fsnotify"
	"github.com/spf13/viper"
)

type MysqlConfig struct {
	Host string `mapstruct:"host"`
	Port int    `mapstruct:"port"`
}
type ServerConfig struct {
	ServerName string      `mapstructure:"name"`
	MysqlInfo  MysqlConfig `mapstructure:"mysql"`
}

func GetEnvInfo(env string) bool {
	viper.AutomaticEnv()
	return viper.GetBool(env)
}
func main() {
	v := viper.New()
	v.SetConfigFile("config.yaml")
	if err := v.ReadInConfig(); err != nil {
		panic(err)
	}
	serverConfig := ServerConfig{}
	if err := v.Unmarshal(&serverConfig); err != nil {
		panic(err)
	}
	fmt.Println(serverConfig)
	fmt.Println(v.Get("name"))
	//动态监听变化
	v.WatchConfig()
	v.OnConfigChange(func(e fsnotify.Event) {
		fmt.Println("config file changed:", e.Name)
		_ = v.ReadInConfig()
		_ = v.Unmarshal(&serverConfig)
		fmt.Println(serverConfig)
	})
	time.Sleep(time.Second * 60)
}
相关推荐
孟陬3 分钟前
Foobar 技术周刊#160:大模型让大规模形式化软件验证成为现实丨AI写C++代码之后会发生什么?丨我们真的需要alpha() 函数吗丨重试,有时会让故障更
前端·后端·typescript
BingoGo4 分钟前
PHP 标准库的价值远不止少写几行代码
后端·php
JaguarJack16 分钟前
PHP 标准库的价值远不止少写几行代码
后端·php·服务端
鶴哥只手遮天35 分钟前
《Redis 8.10.3 深度剖析》系列 · 第 1 章·全景与源码地图:版本谱系、构建体系、全局状态与启动链路
redis·后端·开源
用户4003150433536 分钟前
《从 skynet.timeout 到回调执行:Skynet 分层时间轮源码剖析》
后端
一条Go40 分钟前
四个进程,一把锁:Alioth 的告警评测为什么不需要消息队列
后端·设计模式·架构
Jongkhurun1 小时前
以太网的最小帧长为什么是 64 字节:从 CSMA/CD 冲突窗口推导 64 Byte
网络协议
用户1996143559961 小时前
插件是怎么被安全装进系统的
后端
Pniubi1 小时前
Java为什么要分堆和栈
java·开发语言
愚农搬码1 小时前
自研表单引擎、开源组件二开和商业产品,企业应该如何选择?
后端