go学习笔记——配置

1.读取命令行参数

func main() {
    println("Hello ", os.Args[1])
}

配置arg

输出

Hello World

注意arg[0]是go程序的运行目录

2.使用flag加载环境变量

golang内置的标准库flag,可以用来读取配置文件的路径

func main() {

	var configFilePath = flag.String("conf", "./", "config file path") // flag也支持flag.Bool,flag.Int等用法
	flag.Parse()
	println(*configFilePath)
}

配置

输出

./configs

如果找不到-conf配置的话,才会输出 ./

3.使用toml或者multiconfig加载toml配置文件

1.使用toml

go get github.com/BurntSushi/toml@latest

参考:https://github.com/BurntSushi/toml

config.toml配置

Age = 25
Cats = [ "Cauchy", "Plato" ]
Pi = 3.14
Perfection = [ 6, 28, 496, 8128 ]
DOB = 1987-07-05T05:45:00Z

读取配置

type Config struct {
   Age        int
   Cats       []string
   Pi         float64
   Perfection []int
   DOB        time.Time // requires `import time`
}

func main() {

	buf, err := os.ReadFile("./configs/config.toml")
	tomlData := string(buf)
	if err != nil {
		panic(err)
	}
	var conf Config
	if _, err := toml.Decode(tomlData, &conf); err != nil {
		fmt.Println(err.Error())
	}
	fmt.Println(conf)

}

输出

{25 [Cauchy Plato] 3.14 [6 28 496 8128] 1987-07-05 05:45:00 +0000 UTC}

2.使用multiconfig

go get github.com/koding/multiconfig

参考:https://github.com/koding/multiconfig

读取配置

func main() {

	m := multiconfig.NewWithPath("./configs/config.toml") // supports TOML and JSON

	// Get an empty struct for your configuration
	conf := new(Config)

	// Populated the serverConf struct
	m.MustLoad(conf) // Check for error

	fmt.Printf("%+v\n", conf)

输出

&{Age:25 Cats:[Cauchy Plato] Pi:3.14 Perfection:[6 28 496 8128] DOB:1987-07-05 05:45:00 +0000 UTC}

4.使用viper加载配置文件

安装viper

go get github.com/spf13/viper

在config目录下添加viper.go文件

package config

import "github.com/spf13/viper"

// 全局Viper变量
var Viper = viper.New()

func Load(configFilePath string) error {
	Viper.SetConfigName("config")       // config file name without file type
	Viper.SetConfigType("yaml")         // config file type
	Viper.AddConfigPath(configFilePath) // config file path
	return Viper.ReadInConfig()
}

配置文件

db:
  mysql:
    dsn: root:123456@tcp(127.0.0.1:55000)/test?charset=utf8mb4&parseTime=True

读取配置

func main() {

	var configFilePath = flag.String("conf", "./", "config file path")
	flag.Parse()

	if err := config.Load(*configFilePath); err != nil {
		panic(err)
	}

	println(config.Viper.GetString("db.mysql.dsn"))
}

 配置路径

参考:Go语言微服务框架 - 2.实现加载静态配置文件

viper还提供动态配置的功能,来实现热加载,可以使用go的协程来定时刷新配置

package config

import (
	"flag"
	"fmt"
	"github.com/fsnotify/fsnotify"
	"github.com/spf13/viper"
)

// GlobalConfig 全局Viper变量
var GlobalConfig *viper.Viper

func init() {
	initConfig()
	go dynamicConfig()
}

func initConfig() {
	var configFilePath = flag.String("conf", "./", "config file path")
	flag.Parse()
	GlobalConfig = viper.New()
	GlobalConfig.AddConfigPath(*configFilePath) // config file path
	GlobalConfig.SetConfigName("config")        // config file name without file type
	GlobalConfig.SetConfigType("yaml")          // config file type
	err := GlobalConfig.ReadInConfig()          // 读取配置文件
	if err != nil {                             // 可以按照这种写法,处理特定的找不到配置文件的情况
		if v, ok := err.(viper.ConfigFileNotFoundError); ok {
			fmt.Println(v)
		} else {
			panic(fmt.Errorf("read config err:%s\n", err))
		}
	}
}

// viper支持应用程序在运行中实时读取配置文件的能力。确保在调用 WatchConfig()之前添加所有的configPaths。
func dynamicConfig() {
	GlobalConfig.WatchConfig()
	GlobalConfig.OnConfigChange(func(event fsnotify.Event) {
		fmt.Printf("发现配置信息发生变化: %s\n", event.String())
	})
}

参考:go使用viper读取配置参数热加载

 

posted @ 2015-07-21 16:33  tonglin0325  阅读(244)  评论(0编辑  收藏  举报