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)
}

这个示例展示了:

  1. 基本类型的使用
  2. 嵌套结构体
  3. 默认值设置
  4. 可选字段
  5. 切片的使用
  6. 自定义环境变量名

输出结果将根据设置的环境变量和默认值显示配置内容。


更多关于golang从环境变量读取配置的轻量级插件库envconfig的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于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_URLDB_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)
}

最佳实践

  1. 为不同组件使用不同的前缀
  2. 为生产环境必须的配置设置 required:"true"
  3. 为开发环境提供合理的默认值
  4. 将配置结构体和解析逻辑放在专门的包中
  5. 在应用启动时尽早解析配置

envconfig 是一个简单但功能完善的配置管理解决方案,特别适合基于环境变量的云原生应用配置。

回到顶部