Go里优雅的使用全局配置

全局配置是一个单例,最简单的实现是使用一个全局变量,为了到处都可以使用到,所以常见的做法是有一个包,例如名字叫 global 或者诸如此类的,然后要用到的地方去导入,例如:

package handlers

import (
    "log"

    "github.com/jiajunhuang/demo/global"
)

func Ping() {
    log.Printf("%s", global.Config.RedisURL)
}

不过这样写起来挺麻烦的,所以,不如这样写。首先咱们照样有一个包,叫做 singleton,里面就有 Config 的单例方法:

package singleton

import (
	"sync"

	"github.com/kelseyhightower/envconfig"
)

var (
	config      *Config
	configMutex sync.Mutex
)

type Config struct {
	Debug bool   `envconfig:"debug"`
	DBURL string `envconfig:"db_url"`
}

func GetConfig() *Config {
	if config != nil {
		return config
	}

	configMutex.Lock()
	defer configMutex.Unlock()

	// double check
	if config != nil {
		return config
	}

	config = &Config{}
	envconfig.Process("APP_NAME", config)

	return config
}

于是,咱们就可以这样使用了:

package main

import (
    "github.com/jiajunhuang/demo/singleton"
)

func main() {
    // init config
	_ = singleton.GetConfig()

}

在别的包里,可以这样:

package handlers

import (
    "github.com/jiajunhuang/demo/singleton"
)

var (
	config = singleton.GetConfig()
)

func Haha() {
    println(config.DBURL)
}

若要问我区别,其实没啥太大的区别,只不过呢,写起来更简单了,只要写 config.Blabla 而不是 global.Config.Blabla

就是这样!


更多文章
  • 权限模型(RBAC/ABAC)
  • OIDC(OpenID Connect) 简介
  • 任务队列简介
  • 使用Drone CI构建CI/CD系统
  • PostgreSQL 操作笔记
  • Golang migrate 做数据库变更管理
  • 使用PostgreSQL做搜索引擎
  • Nginx 源码阅读(三): 连接池、内存池
  • Nginx 源码阅读(二): 请求处理
  • Nginx 源码阅读(一): 启动流程
  • Go 泛型简明教程
  • KVM 显卡穿透给 Windows
  • 使用 HTTP Router 处理 Telegram Bot 按钮回调
  • 使用反射(reflect)对结构体赋值
  • GIN 是如何绑定参数的