当前位置: 首页 > news >正文

golang常用库之-配置文件解析 spf13/viper包 | 解析加载配置

文章目录

  • golang常用库之-配置文件解析 spf13/viper包 | 解析&加载配置
    • 一、背景
    • 二、什么是viper
    • 三、为什么选择Viper?🚀
    • 四、viper基础
    • 四、使用demo
      • 1. 利用viper写toml格式的文件
      • 2. 利用viper读取配置文件
      • 3. 监听配置变化
      • 4. 设置默认值
      • 5. 【重要】 使用标志
      • 6. 【重要】反序列化
  • 参考

golang常用库之-配置文件解析 spf13/viper包 | 解析&加载配置

一、背景

在我们开发过程中,像数据库信息、邮件配置和其他的第三方服务密钥等这些固定的信息都会写在配置文件中,而配置文件又有多种表现形式和格式,有 JSON, TOML, YAML各种格式,而且测试环境,开发环境和生产环境用的配置文件也不是同一份。

我们需要一个go 库可以做这件事!

二、什么是viper

github: https://github.com/spf13/viper

viper
美: [ˈvaɪpər]
英: [ˈvaɪpə®]
n. 蝰蛇(一种小毒蛇);毒如蛇蝎的人;险恶的人
网络 冥界亚龙;道奇蝰蛇;蝮蛇

Viper是Go应用程序的完整配置解决方案,
viper 支持Yaml、Json、 TOML、HCL 等格式,读取非常的方便。

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

Viper can be thought of as a registry for all of your applications configuration needs.
Viper可以被认为是您的所有应用程序配置需求的注册表

三、为什么选择Viper?🚀

Viper
参考URL: https://www.cnblogs.com/zc110/articles/14603870.html

在构建现代应用程序时,你无需担心配置文件格式;你想要专注于构建出色的软件。Viper的出现就是为了在这方面帮助你的。

Viper能够为你执行下列操作:

  • 查找、加载和反序列化JSON、TOML、YAML、HCL、INI、envfile和Java properties格式的配置文件。
  • 提供一种机制为你的不同配置选项设置默认值。
  • 提供一种机制来通过命令行参数覆盖指定选项的值。
  • 提供别名系统,以便在不破坏现有代码的情况下轻松重命名参数。
  • 当用户提供了与默认值相同的命令行或配置文件时,可以很容易地分辨出它们之间的区别。

Viper会按照下面的优先级。每个项目的优先级都高于它下面的项目:

  • 显示调用Set设置值
  • 命令行参数(flag)
  • 环境变量
  • 配置文件
  • key/value存储
  • 默认值

四、viper基础

Viper 可以从不同的位置读取配置,不同位置的配置具有不同的优先级,高优先级的配置会覆盖低优先级相同的配置,按优先级从高到低排列如下:

  1. 通过 viper.Set 函数显示设置的配置
  2. 命令行参数
  3. 环境变量
  4. 配置文件
  5. Key/Value 存储
  6. 默认值

四、使用demo

1. 利用viper写toml格式的文件

func init(){
	viper.SetConfigFile("hello.toml")//文件名
	viper.Set("Address","0.0.0.0:9090")//统一把Key处理成小写 Address->address
	err := viper.WriteConfig()//写入文件
	if err != nil { // Handle errors reading the config file
		panic(fmt.Errorf("Fatal error config file: %s \n", err))
	}
}

运行一下,会发现当前目录会出现一个hello.toml的文件
相对于写入配置文件的操作。

2. 利用viper读取配置文件

viper.SetConfigFile("hello.toml")
err := viper.ReadInConfig() // 会查找和读取配置文件
if err != nil { // Handle errors reading the config file
	panic(fmt.Errorf("Fatal error config file: %s \n", err))
}
Address = viper.GetString("Address")
//key取Address或者address都能取到值,反正viper转成小写处理
fmt.Println(Address)

3. 监听配置变化

viper.WatchConfig()
viper.OnConfigChange(func(e fsnotify.Event) {
    fmt.Println("配置发生变更:", e.Name)
})

不建议在实际开发中使用热加载功能,因为即使配置热加载了,程序中的代码也不一定会热加载。例如:修改了服务监听端口,但是服务没有重启,这时候服务还是监听在老的端口上,会造成不一致。

4. 设置默认值

viper.SetDefault("ContentDir", "content")
viper.SetDefault("LayoutDir", "layouts")
viper.SetDefault("Taxonomies", map[string]string{"tag": "tags", "category": "categories"})

5. 【重要】 使用标志

Viper 支持 Pflag 包,能够绑定 key 到 Flag。我们可以将标志绑定到 Viper,这样就可以使用 viper.Get() 获取标志的值。

绑定单个标志

viper.BindPFlag("token", pflag.Lookup("token"))

还可以绑定一组现有的 pflags(pflag.FlagSet):

viper.BindPFlags(pflag.CommandLine) 

注意:工作中,这个常用到,一般都是命令行优先与配置文件,这样配置统一就是viper来管理,最后一次反序列化到我们的配置实例中。

6. 【重要】反序列化

Viper 可以支持将所有或特定的值解析到结构体、map 等。可以通过两个函数来实现:

Unmarshal(rawVal interface{}) error
UnmarshalKey(key string, rawVal interface{}) error
type config struct { 
    Port int 
    Name string 
    PathMap string `mapstructure:"path_map"`
}
var C config
err := viper.Unmarshal(&C)
if err != nil { 
    t.Fatalf("unable to decode into struct, %v", err)
}

Viper 在后台使用 github.com/mitchellh/mapstructure 来解析值,其默认情况下使用mapstructure tags。当我们需要将 Viper 读取的配置反序列到我们定义的结构体变量中时,一定要使用 mapstructure tags。

注意:工作中,这个常用到,这块就是把我们从配置文件中读到内容,反序列化特定的struct实例,方便代码使用。

参考

Viper
参考URL: https://www.cnblogs.com/zc110/articles/14603870.html

相关文章:

  • Rust(7):结构体类型
  • 通信原理学习笔记6-3:数字解调——判决和误码率推导
  • Mybatis快速上手2——通用的CRUD操作
  • 基于Oracle数据库高校学生宿舍管理系统
  • 基于ACS40核心板的串口图传设计
  • Android移动应用开发之ListView和RecyclerView的简单使用
  • 探究linux进程调度
  • android新版本适配-android13最全适配方案
  • 【mongo 系列】聚合知识点梳理
  • 2022年9月26日--10月2日(ue4热更新视频教程为主)
  • 阿里云SLB负载均衡理论与操作
  • 【理论】(spark 二)spark core之RDD:基础概念、特点、stage任务划分与hello spark
  • JWT安全WebGoat实战与预编译CASE注入
  • 贝叶斯公式——假阳性问题
  • ES6-let-难点
  • 【162天】黑马程序员27天视频学习笔记【Day02-上】
  • 0x05 Python数据分析,Anaconda八斩刀
  • angular学习第一篇-----环境搭建
  • C# 免费离线人脸识别 2.0 Demo
  • css的样式优先级
  • Docker: 容器互访的三种方式
  • happypack两次报错的问题
  • isset在php5.6-和php7.0+的一些差异
  • JavaScript 无符号位移运算符 三个大于号 的使用方法
  • php中curl和soap方式请求服务超时问题
  • Python socket服务器端、客户端传送信息
  • XForms - 更强大的Form
  • 代理模式
  • 浮动相关
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 力扣(LeetCode)22
  • 聊聊spring cloud的LoadBalancerAutoConfiguration
  • 三分钟教你同步 Visual Studio Code 设置
  • 实现简单的正则表达式引擎
  • 最简单的无缝轮播
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • Nginx惊现漏洞 百万网站面临“拖库”风险
  • ​MySQL主从复制一致性检测
  • ​如何在iOS手机上查看应用日志
  • #LLM入门|Prompt#1.7_文本拓展_Expanding
  • #微信小程序:微信小程序常见的配置传值
  • (六)vue-router+UI组件库
  • (十八)SpringBoot之发送QQ邮件
  • (五)c52学习之旅-静态数码管
  • (一)kafka实战——kafka源码编译启动
  • (一)VirtualBox安装增强功能
  • (转)GCC在C语言中内嵌汇编 asm __volatile__
  • (转)真正的中国天气api接口xml,json(求加精) ...
  • ... 是什么 ?... 有什么用处?
  • .NET 中使用 Mutex 进行跨越进程边界的同步
  • [C#基础知识]专题十三:全面解析对象集合初始化器、匿名类型和隐式类型
  • [C++]unordered系列关联式容器
  • [CISCN2019 华北赛区 Day1 Web2]ikun
  • [GPT]Andrej Karpathy微软Build大会GPT演讲(上)--GPT如何训练
  • [HTTP]HTTP协议的状态码