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
相关推荐
WEI_YANG_JU3 分钟前
初中数学教学中合作学习的研究与实践
学习
码农小韩7 分钟前
FPGA学习(一)——LED点灯与开发流程
学习·fpga开发·入门·环境配置·仿真·点灯
神仙别闹1 小时前
基于Python实现英词语自动对齐系统
开发语言·python
akinggw1 小时前
libagentcore - 一个基于c++的AI多agent系统升级到2.0版本
开发语言·jvm·c++
李长渊哦1 小时前
Qoder 自定义子智能体(Subagent)学习笔记
chrome·笔记·学习
代码山河1 小时前
基本类型转换:自动类型转换与强制类型转换
java·学习·架构·教程·面向对象·项目
老歌老听老掉牙1 小时前
圆柱端面四平面交线及其在yoz面投影的几何解析与 Python 实现
开发语言·python·平面
旖旎夜光2 小时前
【C++ 基础入门】命名空间、输入输出、缺省参数与函数重载
开发语言·c++·笔记·学习
俩个逗号。。2 小时前
Kotlin flow 详解
android·开发语言·kotlin
microrain2 小时前
SagooIoT 的数据接入层只有四张表,却能接住三种外部数据
物联网·golang·数据建模·sagooiot