Scott

viper 2 years ago

go
3426个字符
共有214人围观

简介

viper是go语言配置文件的一个管理库,github star 23.2K

viper有以下特性:

  • 设置默认值
  • 从json, toml,yaml,envfile 和 java properties格式的配置文件读取配置信息
  • 实时监控和重新读区配置文件
  • 从远程配置系统(etcd或consul)读取并监控配置变化
  • 从命令行参数读取配置
  • 从buffer读区配置
  • 设置显式值

get started

下面来看看viper的简单用法, 以config.yml为例

#install
go get github.com/spf13/viper

目录结构:

package main

import (
  "fmt"
  "github.com/fsnotify/fsnotify"
  "github.com/spf13/viper"
  "log"
  "os"
  "path"
)

type Config struct {
  Use string   `mapstructure:"use"`
  Cfg []Server `mapstructure:"cfg"`
}

type Server struct {
  Name  string   `mapstructure:"name"`
  Host  string   `mapstructure:"host"`
  Port  int      `mapstructure:"port"`
  Likes []string `mapstructure:"likes"`
}

func main() {
  pth := path.Join(os.Getenv("GOPATH"), "src/github.com/scott-x/test")

  // name of config file (without extension)
  viper.SetConfigName("config")
  // REQUIRED if the config file does not have the extension in the name 
  viper.SetConfigType("yaml") 
  // optionally look for config in the working directory  
  viper.AddConfigPath(".") 
  // path to look for the config file in
  viper.AddConfigPath(pth)      

  err := viper.ReadInConfig() // Find and read the config file
  if err != nil {             // Handle errors reading the config file
    panic(fmt.Errorf("fatal error config file: %w", err))
  }

  var config Config
  if err = viper.Unmarshal(&config); err != nil {
    panic("Unmarshal failed:" + err.Error())
  }
  log.Println(config)

  go func() {
    viper.OnConfigChange(func(e fsnotify.Event) {
      fmt.Println("Config file changed:", e.Name)
    })
    viper.WatchConfig()
  }()
}

运行:

在不修改源码的情况下实现线上线下环境分离

思路:

  • 1,线下创建一个环境变量,如果能够读到就为debug模式,否则为生产模式
  • 2,利用flag 命令行指定环境 eg: xx -env debug

下面展示环境变量的用法,eg:

export TEST_ENV=1

代码结构:

package main

import (
  "fmt"
  "github.com/fsnotify/fsnotify"
  "github.com/spf13/viper"
  "log"
  "os"
  "path"
)

type Config struct {
  Mysql `mapstructure:"mysql"`
}

type Mysql struct {
  Host     string `mapstructure:"host"`
  Port     int    `mapstructure:"prot"`
  Username string `mapstructure:"username"`
}

func main() {
  pth := path.Join(os.Getenv("GOPATH"), "src/github.com/scott-x/test/env")
  var configFileName, env string
  if myenv := os.Getenv("TEST_ENV"); len(myenv) > 0 {
    env = "debug"
  } else {
    env = "pro"
  }
  configFileName = fmt.Sprintf("config-%s.yml", env)
  log.Println("configFileName:", configFileName)

  // name of config file (without extension)
  viper.SetConfigName(configFileName) 
  // REQUIRED if the config file does not have the extension in the name 
  viper.SetConfigType("yaml")
  // optionally look for config in the working directory        
  viper.AddConfigPath(".")  
  // path to look for the config file in         
  viper.AddConfigPath(pth)            

  err := viper.ReadInConfig() // Find and read the config file
  if err != nil {             // Handle errors reading the config file
    panic(fmt.Errorf("fatal error config file: %w", err))
  }

  var config Config
  if err = viper.Unmarshal(&config); err != nil {
    panic("Unmarshal failed:" + err.Error())
  }
  log.Println(config)

  go func() {
    viper.OnConfigChange(func(e fsnotify.Event) {
      fmt.Println("Config file changed:", e.Name)
    })
    viper.WatchConfig()
  }()
}

不设置环境变量运行:

设置环境变量后运行: