Go语言学习之配置管理库Viper

一、Viper 是什么

  • Go 生态最常用配置管理库
  • 支持:yaml/json/toml/ini/env/命令行参数
  • 自动监听配置文件热更新
  • 读取配置像读对象一样简单

二、安装依赖

bash 复制代码
go get github.com/gin-gonic/gin
go get github.com/spf13/viper

栗子

bash 复制代码
yangyanping@yangyaningdeAir my-go % 
go get github.com/gin-gonic/gin
go get github.com/spf13/viper

三、项目结构(推荐)

bash 复制代码
├── config/
│   └── server.yaml   # 系统配置文件
    └── mysql.yaml    # mysql配置文件
    └── redis.yaml    # redis配置文件
    └── config.go     # 配置文件加载
├── main.go

四、配置示例

server.yaml

bash 复制代码
server:
  port: 8080
  mode: debug

mysql.yaml

bash 复制代码
mysql:
  host: 127.0.0.1
  port: 3306
  username: root
  password: Yangyanping@1981
  dbname: test

redis.yaml

bash 复制代码
redis:
  addr: localhost:6379
  password: ""
  db: 0

五、config.go 读取配置

Go 复制代码
package config

import (
	"os"
	"path/filepath"

	"github.com/spf13/viper"
)

type MySQLConfig struct {
	Host     string `yaml:"host"`
	Port     int    `yaml:"port"`
	Username string `yaml:"username"`
	Password string `yaml:"password"`
	DBName   string `yaml:"dbname"`
}

type RedisConfig struct {
	Addr     string `yaml:"addr"`
	Password string `yaml:"password"`
	DB       int    `yaml:"db"`
}

type Config struct {
	MySQL MySQLConfig `yaml:"mysql"`
	Redis RedisConfig `yaml:"redis"`
}

var AppConfig Config

func LoadConfig() {
	workDir, err := os.Getwd()
	if err != nil {
		panic("无法获取当前工作目录: " + err.Error())
	}

	configDir := filepath.Join(workDir, "config")
	viper.AddConfigPath(configDir)
	viper.SetConfigType("yaml")

	// 加载 server.yml 配置
	viper.SetConfigName("server")
	if err := viper.ReadInConfig(); err != nil {
		panic("无法读取 server 配置文件: " + err.Error())
	}

	// 加载 mysql.yaml 配置并合并
	viper.SetConfigName("mysql")
	if err := viper.MergeInConfig(); err != nil {
		panic("无法读取 mysql 配置文件: " + err.Error())
	}

	// 加载 redis.yaml 配置并合并
	viper.SetConfigName("redis")
	if err := viper.MergeInConfig(); err != nil {
		panic("无法读取 redis 配置文件: " + err.Error())
	}

	if err := viper.Unmarshal(&AppConfig); err != nil {
		panic("配置反序列化失败: " + err.Error())
	}
}

五、main.go 完整使用示例

Go 复制代码
package main

import (
	"my-go/config"
	"my-go/router"

	"my-go/logs"

	"my-go/database"

	"github.com/gin-gonic/gin"
)

func main() {
	gin.SetMode(gin.ReleaseMode)

	// 初始化日志库
	logs.InitLogger()
	// 加载配置文件
	config.LoadConfig()

	// 初始化数据库
	database.InitDB()
	// 初始化 Redis
	database.InitRedis()

	defer database.CloseDB()

	router := router.SetupRouter()
	router.Use(logs.GinZapLogger()) // 使用 Zap 替代默认 Logger
	router.Use(gin.Recovery())      // Recovery 仍然保留

	// 注册路由...
	router.Run(":8080")
	logs.Logger.Info("服务器已启动,prot:8080")
}

六、Viper 常用读取方法

复制代码
// 字符串
viper.GetString("server.port")

// 数字
viper.GetInt("mysql.port")

// 布尔
viper.GetBool("redis.enable")

// 子树
mysql := viper.Sub("mysql")
host := mysql.GetString("host")

// 读取环境变量
viper.AutomaticEnv()
port := viper.Get("PORT")

七、热加载配置(常用)

复制代码
// 监听配置变化
viper.WatchConfig()
viper.OnConfigChange(func(e fsnotify.Event) {
	fmt.Println("配置文件已修改:", e.Name)
	// 重新解析
	if err := viper.Unmarshal(&AppConfig); err != nil {
		fmt.Println("重新加载失败", err)
	}
})

八、多环境配置(开发 / 测试 / 生产)

复制代码
// 从环境变量读取 mode
mode := viper.Get("MODE")
viper.SetConfigName("config." + mode)
// 然后读取 config.dev.yaml / config.prod.yaml
相关推荐
酿情师29 分钟前
yihan:一款面向连续网页学习的智能侧边栏插件
学习·学习方法·工具·学习工具
九转成圣1 小时前
Java 性能优化实战:如何将海量扁平数据高效转化为类目字典树?
java·开发语言·json
SmartRadio1 小时前
ESP32-S3 双模式切换实现:兼顾手机_路由器连接与WiFi长距离通信
开发语言·网络·智能手机·esp32·长距离wifi
laowangpython1 小时前
Rust 入门:GitHub 热门内存安全编程语言
开发语言·其他·rust·github
我叫汪枫1 小时前
在后台管理系统中,如何递归和选择保留的思路来过滤菜单
开发语言·javascript·node.js·ecmascript
_.Switch1 小时前
东方财富股票数据JS逆向:secids字段和AES加密实战
开发语言·前端·javascript·网络·爬虫·python·ecmascript
软件技术NINI1 小时前
webkit简介及工作流程
开发语言·前端·javascript·udp·ecmascript·webkit·yarn
Brendan_0011 小时前
JavaScript的Stomp.over
开发语言·javascript·ecmascript
念2341 小时前
f5 shape分析
开发语言·javascript·ecmascript
苍穹之跃1 小时前
某量JS逆向
开发语言·javascript·ecmascript