9ed138bc38929e2ae7f5336e036b9e4c
gin框架构建Api之:使用Viper读取配置文件

上节课我们启动了一个简单是server,本节课我们讲解如何读取配置文件,我们使用扩展包viper读取。

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") 即可。

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

初始化配置
主函数中增加配置初始化入口

package main
import (
    "flag"
    "fmt"
    "runtime"
    "net/http"
        "com.api.com/router"
    "github.com/spf13/pflag"
    "github.com/gin-gonic/gin"
    "github.com/spf13/viper"
)
var (
    env = flag.String("env", "product", "run the environment, local qa or product")
)
func main() {
    runtime.GOMAXPROCS(runtime.NumCPU())
    configUrl := pflag.StringP("config", "c", "", "apiserver config file path.")
    flag.Parse()
    //初始化
    system.SetupConfig(*env, *configUrl)
}

在 main 函数中增加了 config.Init(*cfg) 调用,用来初始化配置,cfg 变量值从命令行 flag 传入,可以传值,比如 ./com.api.com -c config.yaml,也可以为空,如果为空会默认读取 conf/config.yaml。

解析配置

main 函数通过 config.Init 函数来解析并 watch 配置文件(函数路径:system/config.go),config.go 源码为:
```
package config
import (
"log"
"strings"
"github.com/fsnotify/fsnotify"
"github.com/spf13/viper"
)
type Cfg struct {
Name string
}
func SetupConfig(env string, configUrl string) {
fmt.Println(env)
c := Cfg{
Name: configUrl,
}
// 初始化配置文件
if err := c.initConfig(env); err != nil {
fmt.Println(err)
log.Error("config load err",err)
return
}
// 监控配置文件变化并热加载程序
c.watchConfig()
// 初始化日志包
c.initLog()
log.Info("start")
//c.initParam()
}
func (c *Cfg) initConfig(env string) error {
if c.Name != "" {
viper.SetConfigFile(c.Name) // 如果指定了配置文件,则解析指定的配置文件
} else {
fmt.Println("init"+ env)
viper.AddConfigPath("conf/" + env) // 如果没有指定配置文件,则解析默认的配置文件
viper.SetConfigName("config")

top Created with Sketch.