golang通过文件环境变量和命令行标志快速配置应用的插件库config的使用
Golang通过文件、环境变量和命令行标志快速配置应用的插件库config使用
特性
- 声明式定义配置的方式
- 只需一行代码即可从文件、环境变量或命令行参数读取配置
- 支持验证功能
示例
config
是一个支持从文件、环境变量和命令行参数读取配置到结构体的包。你只需要声明一个配置结构体并调用Read
方法。
package main
import (
"fmt"
"github.com/num30/config"
)
type Config struct {
DB Database `default:{}`
DebugMode bool `flag:"debug" usage:"enable verbose debug logging"`
}
type Database struct {
Host string `default:"localhost" validate:"required"`
Password string `validate:"required" envvar:"DB_PASS"`
DbName string `default:"mydb"`
Username string `default:"root"`
Port int `default:"5432"`
}
func main() {
var conf Config
err := config.NewConfReader("myconf").Read(&conf)
if err != nil {
panic(err)
}
fmt.Printf("Config %+v", conf)
}
当你想改变应用的数据库主机时,可以通过3种方式实现:
- 在home目录创建配置文件
myconf.yaml
db:
host: "localhost"
-
设置环境变量,如
DB_HOST=localhost
-
设置命令行参数,如
--db.host=localhost
安装
go get github.com/num30/config
设置配置值
ConfReader
按照以下顺序合并来自三个来源的值:
- 文件
- 环境变量
- 命令行参数
在文件中设置的相同键会被环境变量覆盖,而命令行参数具有最高优先级。但是,你可以在文件中设置一个键,在环境变量或命令行参数中设置其他键,这些将被合并。
配置文件
名称
ConfReader
将使用配置名称属性来搜索具有该名称的配置文件。
位置
默认情况下,配置读取器将在home或当前目录中搜索配置文件。你可以通过使用NewConfReader("myconf").WithSearchDirs("/etc/conf")
来覆盖此行为。
引用字段
字段名称从以小写字母开头的驼峰式转换为小写下划线式。例如,如果在代码中你将值引用为DB.DbName
,那么它将转换为:
db:
dbName: "mydb"
格式
配置文件类型可以是任何viper支持的类型:JSON、TOML、YAML、HCL、INI、envfile和Java Properties文件。
环境变量
要通过环境变量设置标志,请将所有字母大写并用’_‘替换路径中的’.’。例如:app.Server.Port -> APP_SERVER_PORT
你可以为环境变量设置前缀。例如NewConfReader("myconf").WithPrefix("MYAPP")
将搜索类似MYAPP_DB_HOST
的环境变量
可以在结构体标签envvar
中设置环境变量名称。例如:
Password string `envvar:"DB_PASS"`
将使用环境变量DB_PASS
的值来配置Password
字段。
命令行参数
要通过命令行参数设置配置字段,你需要传递以--
为前缀的参数和小写的带路径的字段名。如--db.host=localhost
布尔值可以通过仅传递标志名称来设置,如--verbose
你可以通过在字段上使用标签flag:"name"
来覆盖标志的名称。例如:
type Config struct {
DebugMode bool `flag:"debug"`
}
你可以通过调用myapp --debug
来设置标志
验证
你可以通过使用validate
标签来验证配置结构体的字段。例如:
type Config struct {
Host string `validate:"required"`
}
常见问题
- 如何为切片设置值? 如果我们有这样的结构体:
type SliceConf struct {
Slice []string
}
那么我们可以通过以下方式为切片设置值:
- 环境变量
export SLICE="a,b"
- 命令行参数
myapp --slice", "a", "--slice", "b"
- 配置文件
slice: [ "a", "b"]
贡献
我们喜欢帮助!通过fork仓库并打开pull request或创建issue来贡献。
致谢
这个包基于Viper 特别感谢:
- enviper使环境变量与viper一起工作
- defaults使默认值与结构体一起工作
更多关于golang通过文件环境变量和命令行标志快速配置应用的插件库config的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang通过文件环境变量和命令行标志快速配置应用的插件库config的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang 配置管理:使用 config 插件库
在 Go 语言中,管理应用配置有多种方式,包括环境变量、命令行参数和配置文件等。下面我将介绍如何使用流行的 config 插件库来统一管理这些配置源。
安装 config 库
首先安装 config 库:
go get github.com/olebedev/config
基本使用示例
package main
import (
"fmt"
"log"
"os"
"github.com/olebedev/config"
)
type AppConfig struct {
Server struct {
Host string `json:"host"`
Port int `json:"port"`
} `json:"server"`
Database struct {
URL string `json:"url"`
Username string `json:"username"`
Password string `json:"password"`
} `json:"database"`
Debug bool `json:"debug"`
}
func main() {
// 1. 从默认配置文件加载
cfg, err := config.ParseYamlFile("config.yaml")
if err != nil {
log.Printf("Warning: %v, using default config", err)
// 创建默认配置
cfg, err = config.ParseYaml(`
server:
host: localhost
port: 8080
database:
url: localhost:5432
username: postgres
password: postgres
debug: false
`)
if err != nil {
log.Fatal(err)
}
}
// 2. 从环境变量覆盖配置
if host := os.Getenv("APP_SERVER_HOST"); host != "" {
cfg.Set("server.host", host)
}
if port := os.Getenv("APP_SERVER_PORT"); port != "" {
cfg.Set("server.port", port)
}
// 3. 解析到结构体
var appConfig AppConfig
if err := cfg.Unmarshal(&appConfig); err != nil {
log.Fatal(err)
}
fmt.Printf("Final config: %+v\n", appConfig)
}
支持多配置源的高级用法
下面是一个更完整的示例,支持 JSON/YAML 配置文件、环境变量和命令行参数:
package main
import (
"flag"
"fmt"
"log"
"os"
"github.com/olebedev/config"
)
func main() {
// 定义命令行参数
configFile := flag.String("config", "config.yaml", "Path to config file")
debug := flag.Bool("debug", false, "Enable debug mode")
port := flag.Int("port", 0, "Server port")
flag.Parse()
// 尝试加载配置文件
cfg, err := config.ParseYamlFile(*configFile)
if err != nil {
log.Printf("Warning: %v, using default config", err)
cfg, _ = config.ParseYaml("") // 创建空配置
}
// 环境变量覆盖
if envHost := os.Getenv("APP_HOST"); envHost != "" {
cfg.Set("server.host", envHost)
}
if envPort := os.Getenv("APP_PORT"); envPort != "" {
cfg.Set("server.port", envPort)
}
// 命令行参数覆盖(最高优先级)
if *port > 0 {
cfg.Set("server.port", *port)
}
if *debug {
cfg.Set("debug", true)
}
// 获取配置值
host, _ := cfg.String("server.host")
portVal, _ := cfg.Int("server.port")
debugVal, _ := cfg.Bool("debug")
fmt.Printf("Server will run on %s:%d, debug mode: %v\n",
host, portVal, debugVal)
}
配置优先级
通常配置源的优先级如下(从低到高):
- 默认值(代码中硬编码)
- 配置文件(JSON/YAML)
- 环境变量
- 命令行参数
最佳实践
- 配置文件模板:提供一个
config.yaml.example
文件作为模板 - 环境变量命名:使用统一前缀如
APP_
避免冲突 - 敏感信息:不要将密码等敏感信息提交到版本控制
- 配置验证:加载配置后验证必填项和格式
其他替代方案
除了 olebedev/config
,还有其他流行的配置管理库:
- Viper:功能最全,支持多种配置格式和环境变量
- Koanf:轻量级,支持多种配置源和格式
- Envconfig:专注于环境变量到结构体的映射
选择哪个库取决于你的具体需求,对于简单应用,olebedev/config
已经足够;对于复杂需求,Viper 可能是更好的选择。