首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

Viper:强大的Go配置解析库

编程知识
2024年08月20日 07:00

1 介绍

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

  • 设置默认值
  • 从JSON、TOML、YAML、HCL、envfile和Java properties格式的配置文件读取配置信息
  • 实时监控和重新读取配置文件(可选)
  • 从环境变量中读取
  • 从远程配置系统(etcd或Consul)读取并监控配置变化
  • 从命令行参数读取配置
  • 从buffer读取配置
  • 显式配置值

2 Golang项目中的使用

2.1 在go中安装Viper

# 终端中输入如下命令
ArchitePlus@MacBook-Air traffic.demo % go get github.com/spf13/viper

2.2 编写通用配置文件

因为能支持多重配置文件格式,包含 JSON、TOML、YAML、HCL、INI、envfile 和 Java 属性文件,方便开发者根据项目需求选择合适的格式。
我们这边使用yaml做示例。

创建一个conf文件夹,添加子文件夹files,然后在下面添加config.yaml,里面可以放一些基本的、通用的配置信息。

app: # 应用基本配置
  env: local # 环境名称
  port: 8888 # 服务监听端口号
  app_name: traffic-demo # 应用名称
  app_url: http://localhost # 应用访问地址


MySQL: # MySQL配置
  host: 127.0.0.1 # MySQL主机地址
  port: 3306 # MySQL端口号
  user: root # MySQL用户名
  password: <PASSWORD> 
  db_name: traffic # MySQL数据库名

可以看到,我们有两个配置信息,一个是 app,一个是MySQL。

2.3 编写用户自定义配置文件

还有一些用户自定义的配置文件(可能有多个), 是需要根据不同的运行环境(local、dev、beta、prod)来进行区分的.所以我们在config/files/下面创建四个文件夹 localdevbetaprod 四个文件夹,每个文件夹都有一个custom.yaml文件,当 app.env 的值变化的时候,读取的文件也跟着变化,下面是local的信息

white_list: 
  user_id: # 用户列表
  - 063105015
  - 063105024
  - 063105028
  request_path: # 访问路径
  - /api/v1/users
  - /api/v1/ops

2.4 配置映射的结构体

我们需要配置结构体(实体对象)来映射这俩配置,这样的话,后面在调用的时候非常方便。
conf文件夹下面添加子文件夹model,存放解析映射的结构体,这边新增一个config.go和一个custom.go文件,内容如下:

2.4.1 config.go

package config

// 配置文件解析汇总
type Configuration struct {
	App   App   `mapstructure:"app" json:"app" yaml:"app"`
	MYSQL MYSQL `mapstructure:"mysql" json:"mysql" yaml:"mysql"`
}

// 配置文件解析:app
type App struct {
	Env     string `mapstructure:"env" json:"env" yaml:"env"`
	Port    string `mapstructure:"port" json:"port" yaml:"port"`
	AppName string `mapstructure:"app_name" json:"app_name" yaml:"app_name"`
	AppUrl  string `mapstructure:"app_url" json:"app_url" yaml:"app_url"`
}

// 配置文件解析:mysql
type MYSQL struct {
	Host     string `mapstructure:"host" json:"host" yaml:"host"`
	Port     string `mapstructure:"poet" json:"port" yaml:"port"`
	User     string `mapstructure:"user" json:"user" yaml:"user"`
	Password string `mapstructure:"password" json:"password" yaml:"password"`
	DbName   string `mapstructure:"db_name" json:"db_name" yaml:"db_name"`
}

2.4.2 custom.go

package config

type Custom struct {
	WhiteList whiteList `mapstructure:"white_list" json:"white_list" yaml:"white_list"`
}

// 配置文件解析汇总
type whiteList struct {
	UserId      []string `mapstructure:"user_id" json:"user_id" yaml:"user_id"`
	RequestPath []string `mapstructure:"request_path" json:"request_path" yaml:"request_path"`
}

2.5 创建Global全局变量解析

新建一个 global/app.go 文件,定义 Application 结构体,用来存放一些项目启动时的变量,方便调用。
目前先将 viper 结构体和 Configuration 结构体放入,后续会陆续添加其他配置信息。

package global

import (
	"github.com/spf13/viper"
	config "traffic.demo/config/model"
)

// 定义一个全局的Application
type Application struct {
	ConfigViper *viper.Viper
	Config      config.Configuration
	Custom      config.Custom
}

// 初始化Application
var App = new(Application)

2.5 关键步骤:结构体映射逻辑

配置文件要映射到结构体,这样才能把配置数据提取出来,这边创建 bootstrap/config.go 文件,作为核心解析代码的载体,代码如下(代码中的解释已经很清楚了):

package bootstrap

import (
	"fmt"

	"github.com/fsnotify/fsnotify"
	"github.com/spf13/viper"
	"traffic.demo/global"
)

// configAssemble 是一个泛型函数,用于组装配置文件并返回 viper.Viper 指针
//
// 参数:
//
//	configPath string - 配置文件路径
//	viperStruct T - 用来接收配置文件的结构体
//
// 返回值:
//
//	*viper.Viper - viper.Viper 指针
func configAssemble[T any](configPath string, viperStruct T) *viper.Viper {
	// 初始化 viper
	v := viper.New()
	// 配置文件地址
	v.SetConfigFile(configPath)
	// 配置文件类型,yaml
	v.SetConfigType("yaml")
	if err := v.ReadInConfig(); err != nil {
		panic(fmt.Errorf("read config failed: %s \n", err))
	}

	// 监听配置文件
	v.WatchConfig()
	v.OnConfigChange(func(in fsnotify.Event) {
		fmt.Println("config file changed:", in.Name)
		// 重载配置 &global.App.Config
		if err := v.Unmarshal(viperStruct); err != nil {
			fmt.Println(err)
		}
	})
	// 将配置赋值给全局变量 &global.App.Config
	if err := v.Unmarshal(viperStruct); err != nil {
		fmt.Println(err)
	}

	return v
}

// InitializeConfig 初始化配置函数
func InitializeConfig() {
	// 全局应用文件配置路径,这边是我们的具体global config文件地址
	config := "conf/files/config.yaml"
	configAssemble(config, &global.App.Config)

	// 用户自定义的配置(根据不同的运行环境,加载不同的配置文件)
	customConfig := fmt.Sprintf("%s%s%s", "conf/files/", global.App.Config.App.Env, "/custom.yaml")
	configAssemble(customConfig, &global.App.Custom)

}

2.6 整体文件结构如下

image

2.7 运行结果

main.go 代码如下:

package main

import (
	"fmt"
	"traffic.demo/global"
)

// main 函数是程序的入口点
func main() {

    bootstrap.InitializeConfig()
    fmt.Println("Traffic Service Started...!")

	var globalCong = global.App.Config
	fmt.Printf("globalCong: %+v\n", globalCong)
	var customCong = global.App.Custom
	fmt.Printf("customCong: %+v\n", customCong)
}

效果如下:
image

3 总结

Viper 是一个功能强大、简洁、易于的 Go 配置库,帮助开发者轻松管理应用程序的配置,并提供灵活的接入方式

From:https://www.cnblogs.com/wzh2010/p/18364344
本文地址: http://www.shuzixingkong.net/article/1248
0评论
提交 加载更多评论
其他文章 Fluent Editor:一个基于 Quill 2.0 的富文本编辑器,功能强大、开箱即用!
你好,我是Kagol,个人公众号:前端开源星球。带大家一起使用下 Fluent Editor,使用起来基本上和 Quill 没什么区别,只需要重点关注下增强的部分,比如表格、附件、@提醒、表情等模块。
Fluent Editor:一个基于 Quill 2.0 的富文本编辑器,功能强大、开箱即用! Fluent Editor:一个基于 Quill 2.0 的富文本编辑器,功能强大、开箱即用! Fluent Editor:一个基于 Quill 2.0 的富文本编辑器,功能强大、开箱即用!
ollama搭建本地ai大模型并应用调用
1、下载ollama 1)https://ollama.com&#160;进入网址,点击download下载2)下载后直接安装即可。 2、启动配置模型 默认是启动cmd窗口直接输入 1 ollama run llama3 启动llama3大模型&#160;或者启动千问大模型 1 ollama run
ollama搭建本地ai大模型并应用调用 ollama搭建本地ai大模型并应用调用 ollama搭建本地ai大模型并应用调用
Java常用类——包装类 小白版个人推荐
包装类及自动装箱/拆箱 包装类是将Java中的八种基本数据类型封装成的类,所有数据类型都能很方便地与对应的包装类相互转换,以解决应用中要求使用数据类型,而不能使用基本数据类型的情况。 int a = 10; //基本类型的数据 Integer b = new Integer(10); //包装类表示
面试场景题:一次关于线程池使用场景的讨论。
你好呀,我是歪歪。 来一起看看一个关于线程池使用场景上的问题,就当是个场景面试题了。 问题是这样的: 字有点多,我直接给你上个图你就懂了: 前端发起一个生成报表页面的请求,这个页面上的数据由后端多个接口返回,另外由于微服务化了,所以数据散落在每个微服务中,因此需要调用多个下游接口拿到数据进行整合。
面试场景题:一次关于线程池使用场景的讨论。 面试场景题:一次关于线程池使用场景的讨论。 面试场景题:一次关于线程池使用场景的讨论。
C#/.NET/.NET Core技术前沿周刊 | 第 1 期(2024年8.12-8.18)
前言 C#/.NET/.NET Core技术前沿周刊,你的每周技术指南针!记录、追踪C#/.NET/.NET Core领域、生态的每周最新、最实用的技术文章、社区动态、优质项目和学习资源等。让你时刻站在技术前沿,助力技术成长与视野拓宽。 欢迎投稿,推荐或自荐文章/项目/学习资源等。 &#128240
C#/.NET/.NET Core技术前沿周刊 | 第 1 期(2024年8.12-8.18)
5 个有趣的 Python 开源项目「GitHub 热点速览」
本期,我从上周的开源热搜项目中精心挑选了 5 个有趣、好玩的 Python 开源项目。 首先是 PyScript,它可以让你直接在浏览器中运行 Python 代码,不仅支持在 HTML 中嵌入,还能安装第三方库。然后是用 Python 写的“魔法虫洞” magic-wormhole,这是一个无需服务
5 个有趣的 Python 开源项目「GitHub 热点速览」 5 个有趣的 Python 开源项目「GitHub 热点速览」 5 个有趣的 Python 开源项目「GitHub 热点速览」
Antd-React-TreeSelect前端搜索过滤
Antd-React-TreeSelect前端搜索过滤,antd本事是带有搜索的功能,但是在开发过程中发现自带的搜索功能与我们要使用的搜索过滤还是差了好多,在一些时候搜索为了迎合需要不得不这么操作,那么该操作结合了antd官方的搜索操作,因而在看了网上的一些操作后还是与需求不符合,最后实在没有解决办
Antd-React-TreeSelect前端搜索过滤 Antd-React-TreeSelect前端搜索过滤 Antd-React-TreeSelect前端搜索过滤
方法的三种调用形式
在《可以调用Null的实例方法吗?》一文中,我谈到.NET方法的三种调用形式,现在我们就来着重聊聊这个话题。具体来说,这里所谓的三种方法调用形式对应着三种IL指令:Call、CallVirt和Calli。一、三个方法调用指令 二、三种方法调用形式 三、虚方法的分发(virtual dispatch)
方法的三种调用形式 方法的三种调用形式 方法的三种调用形式