golang viper tips

December 15, 2019

简介

vipper是golang下一个配置文件的解决方案,功能强大,也被很多开源项目所引用。主要特性包括:

  • setting defaults
  • reading from JSON, TOML, YAML, HCL, envfile and Java properties config files
  • live watching and re-reading of config files (optional)
  • reading from environment variables
  • reading from remote config systems (etcd or Consul), and watching changes
  • reading from command line flags
  • reading from buffer
  • setting explicit values

具体使用方法就不copy了,主要记录下使用过程中遇到的一些小问题,避免后续再次踩坑。

如何使用

配置文件的解析、使用方法有多种,简单的方法在业务代码中直接调用viper相关的API:

  • Get(key string) : interface{}
  • GetBool(key string) : bool
  • GetFloat64(key string) : float64
  • GetInt(key string) : int
  • GetIntSlice(key string) : []int
  • GetString(key string) : string
  • GetStringMap(key string) : map[string]interface{}
  • GetStringMapString(key string) : map[string]string
  • GetStringSlice(key string) : []string
  • GetTime(key string) : time.Time
  • GetDuration(key string) : time.Duration

这种方案简单,各个go文件中引入viper object,需要时读取。个人不太喜欢这种方式,一是太多地方引入了viper,业务跟配置解决方案耦合太高。二是个人喜欢统一对配置做些前置检查,避免无效配置。将配置相关解析的代码放在一起而非散落各地的维护性也更高。所以一般使用struct来承担解析后的结果。典型代码如下:

Loading...

对应配置文件内容如下:

Loading...

注意struct中的mapstructure标签,作用类似于json标签,用作控制marshal/unmarshal的过程。

另外在对一些复杂数据结构的支持上,如上面的map[int] struct也做了很好的支持,避免二次解析。

其他

如果仅从上面的内容看,viper跟json直接解析一个config.json库没啥差别。但是viper提供了更多的配置的能力。

Viper does the following for you:

  1. Find, load, and unmarshal a configuration file in JSON, TOML, YAML, HCL, INI, envfile or Java properties formats.
  2. Provide a mechanism to set default values for your different configuration options.
  3. Provide a mechanism to set override values for options specified through command line flags.
  4. Provide an alias system to easily rename parameters without breaking existing code.
  5. Make it easy to tell the difference between when a user has provided a command line or config file which is the same as the default.

Viper uses the following precedence order. Each item takes precedence over the item below it:

  • explicit call to Set
  • flag
  • env
  • config
  • key/value store
  • default

个人在项目中遇到个小问题,项目部署使用内部的容器平台,而这种容器平台使用环境变量来映射相关端口等信息。之前在配置文件自己指定端口的方法行不通了。如果之前使用了viper来获取,这个就不再是个问题了,可以通过BindEnv方法来兼容。

Loading...

viper的更多高级特性有待摸索,后续项目需要实际使用时再研究。

See all postsSee all posts