探索Viper-适用于GoLang的完整配置解决方案
作者:mmseoamin日期:2024-02-04

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

前言

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

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

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

目录

前言

Viper简介

快速上手

库的安装

读取配置文件

更多语法

写回配置文件

监听配置文件

注册和使用别名

读取环境变量

封装使用

1.安装库

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

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

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

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

总结


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

Viper简介

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

        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()

    注册和使用别名

    为某个配置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都是一个值得推荐的配置读取解决方案。

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