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
相关推荐
橘子编程2 小时前
UniApp跨端开发终极指南
开发语言·vue.js·uni-app
onlooker66662 小时前
Claude code 源码学习
学习·ai编程·claude code
pixcarp2 小时前
GORM基础入门使用教程
数据库·golang
sinat_255487812 小时前
泛型:超级、扩展、列表·学习笔记
java·windows·学习·算法
冬至喵喵2 小时前
构建 CLI 的 Python 框架:Typer技术介绍
开发语言·chrome·python
呆萌很2 小时前
【GO】结构体定义练习题
golang
世人万千丶2 小时前
Flutter 框架跨平台鸿蒙开发 - 鸿蒙护眼版本2048操作式游戏应用
学习·flutter·游戏·华为·harmonyos·鸿蒙
AbandonForce2 小时前
STL list
开发语言·c++
前端老石人2 小时前
HTML 入门指南:从规范视角建立正确知识体系
开发语言·前端·html