读取配置文件设置全局变量

106 阅读1分钟

配置文件是每个项目必不可少的部分,用来保存应用基本数据、数据库配置等信息,避免要修改一个配置项需要到处找的尴尬。这里我使用 viper 作为配置管理方案,它支持 JSON、TOML、YAML、HCL、envfile、Java properties 等多种格式的配置文件。

创建配置文件 config.yaml

在项目根目录下新建一个文件 config.yaml ,初期先将项目的基本配置放入,后续我们会添加更多配置信息

go get -u github.com/spf13/viper
# config.yaml

app:
  name: go-leo-gin
  port: 8080

mysql:
  host: 127.0.0.1
  port: 3306
  user: root
  password: 123456
  database: demo
  charset: utf8mb4

logger:
  level: info            # 支持:debug / info / warn / error
  file: logs/app.log     # 日志输出文件

创建配置模块 config/config.go

通过viper.SetConfigName、viper.SetConfigType和viper.AddConfigPath方法来设置配置文件的名称、类型和路径。 使用viper.ReadInConfig()来读取配置文件。如果读取失败,它会返回一个错误。

package config

import "github.com/spf13/viper"

type App struct {
    Name string `mapstructure:"name"`
    Port int    `mapstructure:"port"`
}

type MySQLInfo struct {
    Host     string `mapstructure:"host"`
    Port     int    `mapstructure:"port"`
    User     string `mapstructure:"user"`
    Password string `mapstructure:"password"`
    Database string `mapstructure:"database"`
    Charset  string `mapstructure:"charset"`
}

type Logger struct {
    Level string `mapstructure:"level"`
    File  string `mapstructure:"file"`
}

// Config 总配置结构体(对应 config.yaml)
type Config struct {
    App    App       `mapstructure:"app"`
    MySQL  MySQLInfo `mapstructure:"mysql"`
    Logger Logger    `mapstructure:"logger"`
}

var Conf *Config

// InitConfig 初始化配置
func InitConfig() {
    viper.SetConfigName("config") // 不带扩展名
    viper.SetConfigType("yaml")
    viper.AddConfigPath(".") // 当前目录

    if err := viper.ReadInConfig(); err != nil {
       panic("读取配置文件失败: " + err.Error())
    }
    // 将配置赋值给全局变量
    if err := viper.Unmarshal(&Conf); err != nil {
       panic("解析配置文件失败: " + err.Error())
    }

    println("配置加载成功")
}

初始化加载配置(在 main.go 中)

pfunc main() {
  // 初始化配置
  config.InitConfig()

  r := gin.Default()

	// 测试路由
	r.GET("/ping", func(c *gin.Context) {
		c.String(http.StatusOK, "pong")
	})

	// 启动服务器
  addr := fmt.Sprintf(":%d", config.Conf.App.Port)
  r.Run(addr)
}