探索Viper-适用于GoLang的完整配置解决方案

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 探索Viper-适用于GoLang的完整配置解决方案


前言

   前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站https://www.captainbed.cn/kitie。


       对于现代应用程序,尤其大中型的项目来说,在程序启动和运行时,往往需要传入许多参数来控制程序的行为,我们可以通过命令行参数,环境变量,配置文件等方式来将参数传递给程序。而Viper库为Golang语言开发者提供了对不同数据源和不同格式的配置文件的读取,是Go项目读取配置的神器,我们今天就来讲讲如何使用Viper来解析配置信息。

Viper简介



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


设置默认值

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

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

从环境变量中读取

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

从命令行参数读取配置

从buffer读取配置

显式配置值

快速上手

库的安装

viper的安装非常简单,如同其他Go第三方包一样,只需要go get命令即可安装

go get github.com/spf13/viper


导入

import "github.com/spf13/viper"

读取配置文件单个属性

viper.SetConfigFile("./config.yaml")
viper.ReadInConfig()
fmt.Println(viper.Get("我是不区分大小写的key"))


序列化为对象

// 首先声明一个配置映射对象
type DB struct {
  host string
  port string
}
 
func main() {
 
  viper.SetConfigName("config")
  viper.SetConfigType("yaml")
  viper.AddConfigPath(".")
  viper.ReadInConfig() // 读取配置
  var mysql DB
 
  viper.Unmarshal(&mysql) 将读取到的配置序列化为对象
 
  fmt.Println(mysql.host)
  fmt.Println(mysql.port)
}


以上就是viper的简单使用,可以看出使用起来还是很方便简洁的。

更多语法

写回配置文件

此外,viper还支持将配置值写入配置文件,viper提供了四个函数将配置写回文件。

WriteConfig

WriteConfig函数会将配置写入预先设置好路径的配置文件中,如果配置文件存在,则覆盖,如果没有,则创建。

SafeWriteConfig

SafeWriterConfig与WriteConfig函数唯一的不同是如果配置文件存在,则会返回一个错误。

WriteConfigAs

WriteConfigAs与WriteConfig函数的不同是需要传入配置文件保存路径,viper会根据文件后缀判断写入格式。

SafeWriteConfigAs

SafeWriteConfigAs与WriteConfigAs的唯一不同是如果配置文件存在,则返回一个错误。


监听配置文件

viper支持监听配置文件,并会在配置文件发生变化,重新读取配置文件和回调函数,这样可以避免每次配置变化时,都需要重启启动应用的麻烦。

// 设置监听回调
viper.OnConfigChange(func(e fsnotify.Event) {
  fmt.Println("检测到配置文件已更改:", e.Name)
})
 
// 开启监听
viper.WatchConfig()1. //

注册和使用别名

为某个配置key设置别名,这样可以方便我们在不改变key的情况下,使用别的名称访问该配置。

viper.Set("name", "张三")
 
//为name设置一个username的别名
viper.RegisterAlias("username", "name")
 
//通过username可以读取到name的值
fmt.Println(viper.Get("username"))
 
//修改name的配置值,username的值也发生改变
viper.Set("name", "李四")
 
// 输出结果为李四
fmt.Println(viper.Get("username"))
 


读取环境变量

对于读取操作系统环境变量,viper提供了下面五个函数:

  • AutomaticEnv()
  • BindEnv(string...) : error
  • SetEnvPrefix(string)
  • SetEnvKeyReplacer(string...) *strings.Replacer
  • AllowEmptyEnv(bool)

viper读取环境变量,主要有两种方式:

1.开启AutomaticEnv函数,可直接读取环境变量

// 读取不到
fmt.Println(viper.Get("path"))
 
//开始读取环境变量
viper.AutomaticEnv()
 
//会从环境变量读取到该值
fmt.Println(viper.Get("path"))


2.使用BindEnv绑定某个环境变量

//将p绑定到环境变量PATH,注意这里第二个参数是环境变量
viper.BindEnv("p", "PATH")
 
// 通过p读取PATH的值
fmt.Println(viper.Get("p"))

封装使用

1.安装库

go get github.com/spf13/viper


2.编写配置文件,yaml为例

新建config.yaml配置文件,内容如下

app: # 应用基本配置
  env: local # 环境名称
  port: 8080 # 服务监听端口号
  app_name: online-practice-system # 应用名称
  app_url: http://localhost # 应用域名

3.定义配置映射的结构体

这里因为配置有多层,所以我们结构体也要对应多层,我们可以再标签中通过设置mapstructure属性来设置配置的属性名

// Configuration为管理全部配置的父结点
type Configuration struct {
  App      App      `mapstructure:"app" yaml:"app"`
}
// 如果是多层配置,就需要定义多层结构体
type App struct {
    // 在tag标签中加入yaml:"env"`,声明配置对应关系
    Env     string `mapstructure:"env" yaml:"env"`
    Port    string `mapstructure:"port" yaml:"port"`
    AppName string `mapstructure:"app_name" yaml:"app_name"`
    AppUrl  string `mapstructure:"app_url" yaml:"app_url"`
}

4.编写配置读取初始化函数

这里我们定义了初始化函数,将配置读取到自己global包下的App.Config全局变量,这里可以自己选择读取那哪

package bootstrap
import (
  "fmt"
  "github.com/fsnotify/fsnotify"
  "github.com/spf13/viper"
  "online-practice-system/global"
  "os"
)
// viper读取配置文件初始化
func InitializeConfig() *viper.Viper {
  // 设置配置文件路径
  config := "config.yaml"
  // 生产环境可以通过设置环境变量来改变配置文件路径
  if configEnv := os.Getenv("VIPER_CONFIG"); configEnv != "" {
    config = configEnv
  }
  // 初始化 viper
  v := viper.New()
  v.SetConfigFile(config)
  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 fileDriver changed:", in.Name)
    // 重载配置,这里可以进行重启服务器,或者其他操作
    if err := v.Unmarshal(&global.App.Config); err != nil {
      fmt.Println(err)
    }
  })
  // 将配置赋值给全局变量
  if err := v.Unmarshal(&global.App.Config); err != nil {
    fmt.Println(err)
  }
  return v
}

5.主程序启动前调用初始化函数

func main() {
    //  初始化yaml配置文件
    InitializeConfig()
    ///
}


总结


 Viper是一个功能强大且易于使用的配置读取库,它可以帮助我们简化配置的读取和管理过程,提高应用程序的灵活性和可维护性。无论是小型项目还是大型应用程序,Viper都是一个值得推荐的配置读取解决方案。

       最后,感谢阅读,如果文章对您有帮助的话,请多多三连吧~

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
存储 Go 数据安全/隐私保护
Golang 语言怎么使用 Viper 管理配置信息?(下)
Golang 语言怎么使用 Viper 管理配置信息?(下)
108 0
|
7月前
|
Go
【微信公众号】基于golang的公众号开发基本配置
【微信公众号】基于golang的公众号开发基本配置
119 0
|
存储 算法 安全
Golang 实现对配置文件加密
Golang 实现对配置文件加密
|
存储 JSON 监控
Golang 语言怎么使用 Viper 管理配置信息?(上)
Golang 语言怎么使用 Viper 管理配置信息?
63 1
|
6月前
|
消息中间件 Shell Go
GoLang 环境变量与配置
编程语言中的环境变量和配置管理是关键,Go 项目中配置文件不被打包,需通过环境变量解耦代码。
104 0
|
7月前
|
Go
golang学习3,golang 项目中配置gin的web框架
golang学习3,golang 项目中配置gin的web框架
|
7月前
|
Go
golang学习2,golang开发配置国内镜像
golang学习2,golang开发配置国内镜像
|
7月前
|
Go Windows
win10 golang下载安装,及环境变量配置
鄙人之前是使用mac做golang开发的,后来换了台图形工作站,用了windows的系统,因此只得从头下载golang安装,及进行环境变量的配置。比较方便的一点是,之前在mac osx上码的golang代码不用再敲上一遍了,因为golang可以跨平台运行,可以直接从mac上的golang代码复制到windows系统上即可。
92 1
|
IDE Linux Go
Golang安装和配置指南:从零开始的高效开发之旅
Golang安装和配置指南:从零开始的高效开发之旅
|
存储 NoSQL Go
GoRedisLock:Golang保障数据一致性的分布式锁解决方案
在现代分布式系统中,多个节点之间共享资源是常见的需求。然而,并发访问共享资源可能导致数据不一致性和竞争条件。为了解决这些问题,我们需要引入分布式锁。GoRedisLock是一个出色的分布式锁库,它结合了Go语言和Redis的优势,提供了稳定高效的分布式并发控制解决方案。
269 0