golang从环境变量读取配置的轻量级插件库envconfig的使用
Golang从环境变量读取配置的轻量级插件库envconfig的使用
envconfig是一个允许你从环境变量解析配置并填充任意结构体的库。
支持的类型
- 默认支持几乎所有标准类型以及
time.Duration
- 切片和数组
- 任意结构体
- 通过
Unmarshaler
接口支持自定义类型
工作原理
envconfig会根据你的配置结构体层次结构和字段名称来创建环境变量键名。
例如:
var conf struct {
Name string
Shard struct {
Host string
Port int
}
}
这将检查以下3个键:
- NAME 或 name
- SHARD_HOST 或 shard_host
- SHARD_PORT 或 shard_port
灵活的键名命名
envconfig支持在单词边界处有下划线的键名。例如:
var conf struct {
Cassandra struct {
SSLCert string
SslKey string
}
}
这将检查以下所有键:
- CASSANDRA_SSL_CERT, CASSANDRA_SSLCERT, cassandra_ssl_cert, cassandra_sslcert
- CASSANDRA_SSL_KEY, CASSANDRA_SSLKEY, cassandra_ssl_key, cassandra_sslkey
自定义环境变量名
envconfig支持自定义环境变量名:
var conf struct {
Name string `envconfig:"myName"`
}
默认值
envconfig支持默认值:
var conf struct {
Name string `envconfig:"default=Vincent"`
}
可选值
envconfig支持可选值:
var conf struct {
Name string `envconfig:"optional"`
}
跳过字段
envconfig支持跳过结构体字段:
var conf struct {
Internal string `envconfig:"-"`
}
在一个标签中组合多个选项
你可以组合多个选项:
var conf struct {
Name string `envconfig:"default=Vincent,myName"`
}
切片或数组
对于切片或数组,相同的命名规则适用于切片。要将多个元素放入切片或数组中,需要使用逗号分隔它们。
例如:
var conf struct {
Ports []int
}
这将检查键PORTS
:
- 如果变量是
9000
,切片将只包含9000 - 如果变量是
9000,100
,切片将包含9000和100
对于结构体切片,稍微复杂一些。每个标记必须遵循特定格式:{<first field>,<second field>,...}
例如:
var conf struct {
Shards []struct {
Name string
Port int
}
}
这将检查键SHARDS
。示例变量内容:{foobar,9000},{barbaz,20000}
这将导致在Shards
切片中定义两个结构体。
如果要为切片或数组设置默认值,必须使用;
作为分隔符,而不是,
:
var conf struct {
Ports []int `envconfig:"default=9000;100"`
}
同样适用于结构体切片:
var conf struct {
Shards []struct {
Name string
Port int
} `envconfig:"default={foobar;localhost:2929};{barbaz;localhost:2828}"`
}
完整示例
package main
import (
"fmt"
"log"
"os"
"github.com/vrischmann/envconfig"
)
type Config struct {
AppName string `envconfig:"default=myapp"`
Debug bool `envconfig:"optional"`
Database struct {
Host string `envconfig:"default=localhost"`
Port int `envconfig:"default=5432"`
Username string
Password string
}
Features []string `envconfig:"default=feature1;feature2"`
}
func main() {
// 设置环境变量
os.Setenv("DATABASE_USERNAME", "admin")
os.Setenv("DATABASE_PASSWORD", "secret")
os.Setenv("FEATURES", "auth,logging,cache")
var conf Config
if err := envconfig.Init(&conf); err != nil {
log.Fatal(err)
}
fmt.Printf("AppName: %s\n", conf.AppName)
fmt.Printf("Debug: %v\n", conf.Debug)
fmt.Printf("Database: %s:%d\n", conf.Database.Host, conf.Database.Port)
fmt.Printf("Username: %s\n", conf.Database.Username)
fmt.Printf("Password: %s\n", conf.Database.Password)
fmt.Printf("Features: %v\n", conf.Features)
}
这个示例展示了:
- 基本类型的使用
- 嵌套结构体
- 默认值设置
- 可选字段
- 切片的使用
- 自定义环境变量名
输出结果将根据设置的环境变量和默认值显示配置内容。
更多关于golang从环境变量读取配置的轻量级插件库envconfig的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang从环境变量读取配置的轻量级插件库envconfig的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang 环境变量配置库 envconfig 使用指南
envconfig 是一个轻量级的 Go 库,用于将环境变量映射到结构体字段,简化配置管理。下面详细介绍其使用方法。
安装
go get github.com/kelseyhightower/envconfig
基本用法
1. 定义配置结构体
type Config struct {
Port int `envconfig:"PORT" default:"8080"`
DatabaseURL string `envconfig:"DATABASE_URL" required:"true"`
Debug bool `envconfig:"DEBUG"`
Timeout time.Duration `envconfig:"TIMEOUT" default:"5s"`
}
envconfig
标签指定环境变量名default
标签设置默认值required:"true"
表示该字段必须设置
2. 解析环境变量
package main
import (
"fmt"
"log"
"github.com/kelseyhightower/envconfig"
)
func main() {
var cfg Config
err := envconfig.Process("", &cfg)
if err != nil {
log.Fatal(err.Error())
}
fmt.Printf("Port: %d\n", cfg.Port)
fmt.Printf("DatabaseURL: %s\n", cfg.DatabaseURL)
fmt.Printf("Debug: %t\n", cfg.Debug)
fmt.Printf("Timeout: %v\n", cfg.Timeout)
}
高级特性
1. 前缀支持
可以为环境变量设置前缀,避免命名冲突:
type Config struct {
Port int `envconfig:"PORT"`
}
func main() {
var cfg Config
// 会查找 MYAPP_PORT 环境变量
err := envconfig.Process("myapp", &cfg)
// ...
}
2. 嵌套结构体
type DatabaseConfig struct {
URL string `envconfig:"URL" required:"true"`
Pool int `envconfig:"POOL" default:"10"`
}
type Config struct {
Port int `envconfig:"PORT"`
Database DatabaseConfig `envconfig:"DB"`
}
对应的环境变量名为 DB_URL
和 DB_POOL
3. 切片支持
type Config struct {
Hosts []string `envconfig:"HOSTS" default:"localhost,127.0.0.1"`
}
环境变量值用逗号分隔:HOSTS=host1,host2,host3
4. 自定义解码器
对于复杂类型,可以实现 Decoder
接口:
type IPAddr net.IP
func (ip *IPAddr) Decode(value string) error {
*ip = IPAddr(net.ParseIP(value))
return nil
}
type Config struct {
Host IPAddr `envconfig:"HOST"`
}
完整示例
package main
import (
"fmt"
"log"
"time"
"github.com/kelseyhightower/envconfig"
)
type DatabaseConfig struct {
URL string `envconfig:"URL" required:"true"`
PoolSize int `envconfig:"POOL_SIZE" default:"10"`
Timeout time.Duration `envconfig:"TIMEOUT" default:"5s"`
}
type Config struct {
Port int `envconfig:"PORT" default:"8080"`
Environment string `envconfig:"ENV" default:"development"`
Debug bool `envconfig:"DEBUG"`
Database DatabaseConfig `envconfig:"DB"`
AllowedIPs []string `envconfig:"ALLOWED_IPS" default:"127.0.0.1,::1"`
}
func main() {
var cfg Config
err := envconfig.Process("myapp", &cfg)
if err != nil {
log.Fatalf("Failed to process env vars: %v", err)
}
fmt.Printf("Server Config:\n")
fmt.Printf(" Port: %d\n", cfg.Port)
fmt.Printf(" Environment: %s\n", cfg.Environment)
fmt.Printf(" Debug: %t\n", cfg.Debug)
fmt.Printf("Database Config:\n")
fmt.Printf(" URL: %s\n", cfg.Database.URL)
fmt.Printf(" PoolSize: %d\n", cfg.Database.PoolSize)
fmt.Printf(" Timeout: %v\n", cfg.Database.Timeout)
fmt.Printf("Allowed IPs: %v\n", cfg.AllowedIPs)
}
最佳实践
- 为不同组件使用不同的前缀
- 为生产环境必须的配置设置
required:"true"
- 为开发环境提供合理的默认值
- 将配置结构体和解析逻辑放在专门的包中
- 在应用启动时尽早解析配置
envconfig 是一个简单但功能完善的配置管理解决方案,特别适合基于环境变量的云原生应用配置。