Viper 是 Go 生态中最流行的配置管理库,它支持多种配置格式和环境变量,提供了强大的配置管理能力。下面我将详细介绍 Viper 的使用方法。
我们网站:gofly.v1kf.com
go get github.com/spf13/viper
package main
import (
"fmt"
"github.com/spf13/viper"
)
func main() {
// 设置配置文件名(不需要扩展名)
viper.SetConfigName("config")
// 设置配置文件类型
viper.SetConfigType("yaml") // 支持 "json", "toml", "yaml", "yml", "properties", "props", "prop", "env", "dotenv"
// 添加配置文件搜索路径
viper.AddConfigPath(".") // 当前目录
viper.AddConfigPath("$HOME/.app") // 用户家目录
viper.AddConfigPath("/etc/app/") // 系统目录
// 设置默认值
viper.SetDefault("server.port", 8080)
viper.SetDefault("server.env", "development")
// 读取配置文件
if err := viper.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
fmt.Println("配置文件未找到,使用默认值")
} else {
panic(fmt.Errorf("读取配置文件错误: %w", err))
}
}
// 获取配置值
port := viper.GetInt("server.port")
env := viper.GetString("server.env")
fmt.Printf("服务运行在 %d 端口,环境: %s\n", port, env)
}
config.yaml
示例:
server:
port: 8081
env: production
database:
host: "localhost"
port: 5432
username: "admin"
password: "secret"
config.json
示例:
{
"server": {
"port": 8081,
"env": "production"
},
"database": {
"host": "localhost",
"port": 5432,
"username": "admin",
"password": "secret"
}
}
Viper 可以自动读取环境变量,并可以与配置文件配合使用:
// 设置环境变量前缀(自动转为大写)
viper.SetEnvPrefix("APP") // 将查找 APP_ 开头的环境变量
// 自动绑定所有环境变量
viper.AutomaticEnv()
// 手动绑定特定环境变量
viper.BindEnv("server.port", "APP_SERVER_PORT")
// 环境变量优先级高于配置文件
fmt.Println("最终端口:", viper.GetInt("server.port"))
Viper 可以与 pflag
或标准库 flag
集成:
import "github.com/spf13/pflag"
// 绑定命令行参数
pflag.Int("port", 8080, "服务器端口")
pflag.Parse()
viper.BindPFlags(pflag.CommandLine)
// 现在可以通过 viper.GetInt("port") 获取值
// 启用配置监听
viper.WatchConfig()
// 配置变更回调
viper.OnConfigChange(func(e fsnotify.Event) {
fmt.Println("配置文件已修改:", e.Name)
fmt.Println("新端口:", viper.GetInt("server.port"))
})
// 读取嵌套配置
dbHost := viper.GetString("database.host")
// 或者获取整个子配置
sub := viper.Sub("database")
if sub != nil {
dbPort := sub.GetInt("port")
}
type ServerConfig struct {
Port int `mapstructure:"port"`
Env string `mapstructure:"env"`
}
type DatabaseConfig struct {
Host string `mapstructure:"host"`
Port int `mapstructure:"port"`
Username string `mapstructure:"username"`
Password string `mapstructure:"password"`
}
type Config struct {
Server ServerConfig `mapstructure:"server"`
Database DatabaseConfig `mapstructure:"database"`
}
var cfg Config
if err := viper.Unmarshal(&cfg); err != nil {
panic(err)
}
fmt.Printf("完整配置: %+v\n", cfg)
viper.SetConfigName("config")
viper.AddConfigPath(".")
if err := viper.ReadInConfig(); err != nil {
panic(err)
}
// 读取第二个配置文件并合并
viper.SetConfigName("config.local")
if err := viper.MergeInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
panic(err)
}
}
配置优先级管理:
viper.Set()
设置的值优先级最高安全建议:
viper.SetConfigPermissions(os.FileMode(0600))
设置配置文件权限配置验证:
if viper.GetInt("server.port") <= 0 {
panic("端口号必须大于0")
}
多环境支持:
env := os.Getenv("APP_ENV")
if env == "" {
env = "development"
}
viper.SetConfigName("config." + env)
Viper 提供了强大而灵活的配置管理能力,可以满足从简单到复杂的各种配置需求。通过合理组织配置文件和利用 Viper 的各种功能,可以大大简化应用程序的配置管理工作。