Go语言从入门到精通 -【web项目实战篇】- 读取配置文件

本节核心内容

  • 介绍 Viper
  • 介绍 如何配置 Viper 并读取其配置,以及配置的高级用法

本小节视频教程和代码:百度网盘

可先下载视频和源码到本地,边看视频边结合源码理解后续内容,边学边练。

附带golang.org包的下载地址

Viper 简介

Viper 是国外大神 spf13 编写的开源配置解决方案,具有如下特性:

  • 设置默认值
  • 可以读取如下格式的配置文件:JSON、TOML、YAML、HCL
  • 监控配置文件改动,并热加载配置文件
  • 从环境变量读取配置
  • 从远程配置中心读取配置(etcd/consul),并监控变动
  • 从命令行 flag 读取配置
  • 从缓存中读取配置
  • 支持直接设置配置项的值

Viper 配置读取顺序:

  • viper.Set() 所设置的值
  • 命令行 flag
  • 环境变量
  • 配置文件
  • 配置中心:etcd/consul
  • 默认值

从上面这些特性来看,Viper 毫无疑问是非常强大的,而且 Viper 用起来也很方便,在初始化配置文件后,读取配置只需要调用 viper.GetString()viper.GetInt()viper.GetBool() 等函数即可。

Viper 也可以非常方便地读取多个层级的配置,比如这样一个 YAML 格式的配置:

common:
  database:
    name: test
    host: 127.0.0.1

如果要读取 host 配置,执行 viper.GetString("common.database.host") 即可。

apiserver 采用 YAML 格式的配置文件,采用 YAML 格式,是因为 YAML 表达的格式更丰富,可读性更强。

获取viper.Set()的值

func main() {
        //获取viper.Set()
        viper.Set("name","jeck")
        fmt.Println(viper.GetString("name"))
}       

使用viper获取Set()函数添加的值很简单,直接再Get出来就好。

读取配置文件

func main() {

        viper.AddConfigPath("conf")
        viper.SetConfigName("config")
        viper.ReadInConfig()
        
        fmt.Println(viper.GetString("common.database.host"))
}

代码解析:

  1. viper.AddConfigPath("conf")用来指定yaml配置文件的路径
  2. viper.SetConfigName("config")用来指定配置文件的名称
  3. viper.ReadInConfig()是解析配置文件的函数,如果配置文件的路径错误获名称错误则解析失败,会报错误
  4. viper.GetString("db.uri")是用来从配置文件中根据层级关系来获取数据
  5. 最后,通过fmt.Println()对数据结果进行输出

代码优化

使用viper读取配置文件的代码虽然很简单,但如果我们在开发中每次读取配置文件时都这样一遍遍写的话,那代码量就太大了,因此我们可以通过抽取的方式对代码进行优化,这样只需要在关键地方调用就可以了

main 函数通过 config.Init 函数来解析并 watch 配置文件(函数路径:config/config.go),config.go 源码为:

package config

import "github.com/spf13/viper"

//Init读取初始化配置文件
func Init() error {
        viper.AddConfigPath("conf")
        viper.SetConfigName("config")
        err := viper.ReadInConfig()
        if err != nil {
                return err
        }
        return nil
}

通过将代码抽离出来,这样我们就只需要在读取配置前调用一下config.Init()方法就可以了。

Viper 高级用法

从环境变量读取配置

Viper 可以从环境变量读取配置,这是个非常有用的功能。现在越来越多的程序是运行在 Kubernetes 容器集群中的,在 API 服务器迁移到容器集群时,可以直接通过 Kubernetes 来设置环境变量,然后程序读取设置的环境变量来配置 API 服务器。读者不需要了解如何通过 Kubernetes 设置环境变量,只需要知道 Viper 可以直接读取环境变量即可。

func main() {
        viper.AutomaticEnv()
        if env := viper.Get("GOROOT"); env == nil {
                println("error!")
        } else {
                fmt.Printf("%#v\n", env)
        }
}

代码解析:

  1. viper.AutomaticEnv()用来读取匹配的环境变量
  2. viper.Get("GOROOT")获取GOPOOT的环境变量,当获取不到时,env为空,我们通过println()函数来输出格式后的error
  3. fmt.Printf("%#v\n", env)输出结果

小结

本小节展示了如何用强大的配置管理工具 Viper 来解析配置文件并读取配置,还演示了 Viper 的高级用法。