摒弃世俗浮躁
追求技术精湛

Golang笔记(十一):配置和环境变量

说明

数据库连接信息、会话加密的 KEY、HTTP 服务的监听端口等,目前我们都写死在代码里面,一方面是不好维护,另一方面是项目的适用性很差,无法适用于不同环境。

Viper

spf13/viper 是一个非常优秀的第三方库,GitHub 上一万多个 star 也说明了其受欢迎程度。
Viper 是适用于 Go 应用程序的完整配置解决方案。它支持大部分类型的配置需求和格式。功能如下:

  • 设置默认值
  • 从 JSON,TOML,YAML,HCL,envfile 和 Java 属性配置文件中读取
  • 实时观看和重新读取配置文件(可选)
  • 从环境变量中读取
  • 从远程配置系统(etcd 或 Consul)中读取,并监控变更
  • 从命令行中读取
  • 从缓冲区读取
  • 设置显式值

安装

$ go get github.com/spf13/viper

如何使用?

下面进行了一个简单的封装,里面的 init 方法是加载 .env 的环境变量信息,而除了 Env 以外的其他方法,都是为了处理配置信息而存在。
需要区分一个环境变量和配置信息。环境变量是在 .env 里设置,配置信息是在 config 目录的文件里配置。环境变量我们不需要加入到版本控制器里,而配置信息需要。环境变量每个项目都不一样,配置信息代码是一致的。

pkg/config/config.go:

package config

import (
	"GoBlog/pkg/logger"
	"github.com/spf13/cast"
	"github.com/spf13/viper"
)

// Viper Viper 库实例
var Viper *viper.Viper

// StrMap 简写 map[string]interface{}
type StrMap map[string]interface{}

// init 函数在 import 的时候立刻被加载
func init() {
	// 1. 初始化 Viper 库
	Viper = viper.New()
	// 2. 设置文件名称
	Viper.SetConfigName(".env")
	// 3. 配置类型,支持 "json", "toml", "yaml", "properties", "props", "prop", "env", "dotenv"
	Viper.SetConfigType("env")
	// 4. 环境变量配置文件查找的路径,相对于 main.go
	Viper.AddConfigPath(".")
	// 5. 开始读根目录下的 .env 文件,读到不会报错
	err := Viper.ReadInConfig() 
	logger.LogError(err)
	// 6. 设置环境变量前缀,用以区分 Go 的系统环境变量
	Viper.SetEnvPrefix("appenv")
	// 7. Viper.Get() 时,优先读取环境变量
	Viper.AutomaticEnv()
}

// Env 读取环境变量,支持默认值
func Env(envName string, defaultValue ...interface{}) interface{} {
	if len(defaultValue) > 0 {
		return Get(envName, defaultValue[0])
	}
	return Get(envName)
}

// Add 新增配置项
func Add(name string, configuration map[string]interface{}) {
	Viper.Set(name, configuration)
}

// Get 获取配置项,允许使用点式获取,如 app.name
func Get(path string, defaultValue ...interface{}) interface{} {
	// 不存在的情况
	if !Viper.IsSet(path) {
		if len(defaultValue) > 0 {
			return defaultValue[0]
		}
		return nil
	}
	return Viper.Get(path)
}

// GetString 获取 String 类型的配置信息
func GetString(path string, defaultValue ...interface{}) string {
	return cast.ToString(Get(path, defaultValue...))
}

// GetInt 获取 Int 类型的配置信息
func GetInt(path string, defaultValue ...interface{}) int {
	return cast.ToInt(Get(path, defaultValue...))
}

// GetInt64 获取 GetInt64 类型的配置信息
func GetInt64(path string, defaultValue ...interface{}) int64 {
	return cast.ToInt64(Get(path, defaultValue...))
}

// GetUint 获取 Uint 类型的配置信息
func GetUint(path string, defaultValue ...interface{}) uint {
	return cast.ToUint(Get(path, defaultValue...))
}

// GetBool 获取 Bool 类型的配置信息
func GetBool(path string, defaultValue ...interface{}) bool {
	return cast.ToBool(Get(path, defaultValue...))
}

使用上述代码来管理配置信息

config/database.go:

package config

import (
    "goblog/pkg/config"
)

func init() {

    config.Add("database", config.StrMap{
        "mysql": map[string]interface{}{

            // 数据库连接信息
            "host":     config.Env("DB_HOST", "127.0.0.1"),
            "port":     config.Env("DB_PORT", "3306"),
            "database": config.Env("DB_DATABASE", "goblog"),
            "username": config.Env("DB_USERNAME", ""),
            "password": config.Env("DB_PASSWORD", ""),
            "charset":  "utf8mb4",

            // 连接池配置
            "max_idle_connections": config.Env("DB_MAX_IDLE_CONNECTIONS", 100),
            "max_open_connections": config.Env("DB_MAX_OPEN_CONNECTIONS", 25),
            "max_life_seconds":     config.Env("DB_MAX_LIFE_SECONDS", 5*60),
        },
    })
}
赞(1) 打赏
未经允许不得转载:时光日记 » Golang笔记(十一):配置和环境变量

评论 抢沙发

评论前必须登录!

 

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫

微信扫一扫

登录

找回密码

注册