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
相关推荐
jimy11 小时前
c++的 Type Traits (一)
开发语言·c++
别动我齐刘海2 小时前
Linux 系统调试学习2
linux·运维·c++·人工智能·学习·机器学习·机器人
Web极客码2 小时前
Python Ollama 本地 Agent 入门与订单查询实践
开发语言·jvm·python
m4Rk_2 小时前
【论文阅读】Agent 记忆机制(99):PrisMem——从整体分数搜索走向能力驱动的记忆自进化
论文阅读·人工智能·学习·开源·github
kimnoic2 小时前
PHP 8.2的DNF类型怎么用才规范
开发语言·php
_Evan_Yao2 小时前
前后端联调怎么排查问题?从 Network 到后端日志,一步步定位错误
开发语言·后端·团队开发·需求分析
hudd6682 小时前
JavaEE 初阶 - 多线程(进阶)
java·开发语言·java-ee
小白快快跑哦3 小时前
python-字符串全解(六):正则表达式-前后相断言
开发语言·python·正则表达式·前后相断言
kimnoic3 小时前
Python数据分析中正则表达式匹配字符串与常用函数示例详解
开发语言·python
中屹指纹浏览器svip3 小时前
打开账号环境网页报错,常见原因有哪些?
服务器·开发语言·php·中屹指纹浏览器