1.读取命令行参数
1 2 3 4
| func main() { println("Hello ", os.Args[1]) }
|
配置arg
输出
注意arg[0]是go程序的运行目录
2.使用flag加载环境变量
golang内置的标准库flag,可以用来读取配置文件的路径
1 2 3 4 5 6 7
| func main() {
var configFilePath = flag.String("conf", "./", "config file path") // flag也支持flag.Bool,flag.Int等用法 flag.Parse() println(*configFilePath) }
|
配置
输出
如果找不到-conf配置的话,才会输出 ./
3.使用toml或者multiconfig加载toml配置文件
1.使用toml
1 2
| go get github.com/BurntSushi/toml@latest
|
参考:https://github.com/BurntSushi/toml
config.toml配置
1 2 3 4 5 6
| Age = 25 Cats = [ "Cauchy", "Plato" ] Pi = 3.14 Perfection = [ 6, 28, 496, 8128 ] DOB = 1987-07-05T05:45:00Z
|
读取配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| 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)
}
|
输出
1 2
| {25 [Cauchy Plato] 3.14 [6 28 496 8128] 1987-07-05 05:45:00 +0000 UTC}
|
2.使用multiconfig
1 2
| go get github.com/koding/multiconfig
|
参考:https://github.com/koding/multiconfig
读取配置
1 2 3 4 5 6 7 8 9 10 11 12
| 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)
|
输出
1 2
| &{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
1 2
| go get github.com/spf13/viper
|
在config目录下添加viper.go文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 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() }
|
配置文件
1 2 3 4
| db: mysql: dsn: root:123456@tcp(127.0.0.1:55000)/test?charset=utf8mb4&parseTime=True
|
读取配置
1 2 3 4 5 6 7 8 9 10 11 12
| 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的协程来定时刷新配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| 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读取配置参数热加载