【Go】Go viper 配置模块

ops/2025/3/6 0:55:11/

1. 配置相关概念

在项目开发过程中,一旦涉及到与第三方中间件打交道就不可避免的需要填写一些配置信息,例如 MySQL 的连接信息、Redis 的连接信息。如果这些配置都采用硬编码的方式无疑是一种不优雅的做法,有以下缺陷:

  • 不同环境(开发环境、测试环境、线上环境)之间无法做到环境隔离
  • 信息分散,无法做到集中统一管理
  • 与业务代码相耦合,无法灵活调整

因此配置模块应运而生,这也是为什么在 Go 项目中需要引入 viper 配置模块的原因!

1.1 配置的来源与优先级

在项目中我们可以从不同地方读取配置,常见的配置信息的来源有如下几类:

  1. 命令行参数:往往是启动项目时读取的,比如 mockgen 命令行有 source、destination、package等等参数
  2. 环境变量:配置信息也可以从操作系统当中设置的环境变量中读取
  3. 本地配置文件:比如在 Java 项目中,常常会用 application.yaml 类似的格式保存配置信息
  4. 远程配置中心:这是一个独立的服务,比如 nacos、etcd 就是常见的配置中心

对于上面常见的四种配置来源,如果相互之间冲突会有什么影响呢?这就涉及到配置来源的优先级了,一般来说优先级如下:命令行启动参数 > 本地配置文件 -> 系统环境变量 -> 远程配置中心

💡 温馨提示:上述优先级排列仅个人观点,不同公司有不同的规范标准!

2. viper 简介

viper 是一个 Go 项目当中的配置框架,在项目中引入 viper 可以轻松的读取配置信息当中设定的参数并在项目中加以使用

⭐ viper项目地址:https://github.com/spf13/viper

3. viper 快速入门

3.1 viper 读取配置文件

首先我们需要先在项目中编写配置文件,内容如下:

db:mysql:# mysql dsn连接字符串dsn: root:QWEzxc123456@tcp(localhost:3306)/webook
redis:# redis 连接地址addr: localhost:6379

该配置文件对应的存储路径位于config/dev.yaml

step1:首先我们需要设定好读取的配置文件的名称以及文件后缀,对应 API 如下:

  • AddConfigPath:设定配置文件所在跟路径
  • SetConfigName:设定配置文件名称
  • SetConfigType:设定配置文件类型
  • SetConfigFile:设定配置文件路径(可以替换上述三个参数)
  • SetDefault:设定默认值
  • ReadInConfig:读取配置文件
func InitViperLocal() {// 1. 设置配置文件路径viper.AddConfigPath("config")// 2. 设置配置文件名称viper.SetConfigName("dev")// 3.设置配置文件类型viper.SetConfigType("yaml")// 4. 进行读取err := viper.ReadInConfig()if err != nil {panic(err)}
}

step2:然后我们就可以尝试在项目中进行读取,对应 API 如下:

  • GetString:读取指定 key 对应的字符串数据
  • UnmarshalKey:读取指定 key 对应的数据到反序列化到指定结构体当中
func main() {InitViperLocal()// 1. 读取字符串数据dsn := viper.GetString("db.mysql.dsn")fmt.Println(dsn)// 2. 读取数据反序列到结构体当中var dbConfig DBConfigerr := viper.UnmarshalKey("db.mysql", &dbConfig)if err != nil {panic(err)}fmt.Println(dbConfig)
}

程序运行结果:

💡 温馨提示:如果在 GoLand 中无法读取配置文件路径,有可能是因此 Working Directory 工作目录的设置错误,在 IDE 做相应调整即可!

3.2 viper 读取启动参数

viper 还有一个特别好用的特性:可以通过读取命令行参数实现不同环境配置文件的隔离,比如在此项目中我们设定的配置文件路径为config/dev.yaml,因此我们在命令行参数中指定为--config=config/dev.yaml,如果想要设定测试环境就可以指定命令行参数为:--config=config/test.yaml,因此只需要使用 viper 读取命令行参数来设定配置文件路径即可!

step1:在 Goland 中设定运行时的启动命令行参数

step2:首先我们需要读取命令行当中的参数,对应 API 如下:

  • pflag.String:设置从命令行中读取的参数名称、默认值、说明
  • pflag.Parse:解析读取到的命令行参数
func InitViperCLI() {// 1. 读取命令行参数s := pflag.String("config", "", "配置文件路径")// 2. 解析参数pflag.Parse()// 3. 设定配置文件路径viper.SetConfigFile(*s)// 4. 读取配置err := viper.ReadInConfig()if err != nil {panic(err)}
}

step3:然后我们就可以尝试在项目中正常读取

func main() {//InitViperLocal()InitViperCLI()// 1. 读取字符串数据addr := viper.GetString("redis.addr")fmt.Println(addr)
}

程序运行结果:

3.3 viper 读取配置中心

3.3.1 安装 etcd

step1:使用 Docker 安装 etcd,docker-compose.yaml 文件内容如下:

version: "3"
services:# 配置etcdetcd:image: "bitnami/etcd:latest"restart: alwaysentrypoint:- ALLOW_NON_AUTHENTICATION=yesports:- "12379:2379"

然后在同级目录运行docker compose up启动:

step2:安装 etcdctl 工具,下载源码包:git clone [https://github.com/etcd-io/etcd.git](https://github.com/etcd-io/etcd.git),切换到正式版本tag中,进入etcdctl目录执行go install .命令

然后就会在GOPATH/bin目录下生成对应工具,运行etcdctl命令进行验证

3.3.2 使用 viper 接入 etcd

step1:使用 etcdctl 工具存储配置文件:etcdctl --endpoints=127.0.0.1:2379 put /viper_demo "$(<dev.yaml)"

step2:在项目中通过以下 API 读取远程配置:

  • AddRemoteProvider:设置远程配置中心名称、地址、路径
  • ReadRemoteConfig:读取远程配置
func InitViperRemote() {// 1. 连接远程配置中心err := viper.AddRemoteProvider("etcd3", "127.0.0.1:2379", "/viper_demo")if err != nil {panic(err)}// 2. 读取配置err = viper.ReadRemoteConfig()if err != nil {panic(err)}
}

step3:在项目中匿名导入下面这个包:_ “github.com/spf13/viper/remote”

step4:在主函数中读取配置,验证结果:

func main() {//InitViperLocal()//InitViperCLI()InitViperRemote()// 1. 读取字符串数据addr := viper.GetString("redis.addr")fmt.Println(addr)
}

程序运行结果如下:

3.4 viper 监听配置变更

viper 提供了下列 API 用于监听配置文件的变更并执行对应的回调函数

  • WatchConfig:执行监听本地配置文件的变更
  • WatchRemoteConfig:执行监听远程配置中心的变更
  • OnConfigChange:当配置文件某个 Key 变更时执行对应的回调函数
func InitViperLocal() {// 1. 设置配置文件路径viper.AddConfigPath("config")// 2. 设置配置文件名称viper.SetConfigName("dev")// 3.设置配置文件类型viper.SetConfigType("yaml")// 4. 进行读取err := viper.ReadInConfig()if err != nil {panic(err)}// 5. 开启监听viper.WatchConfig()// 6. 设置变更回调viper.OnConfigChange(func(e fsnotify.Event) {fmt.Println("config file changed:", e.Name)fmt.Println(viper.GetString("db.mysql.dsn"))fmt.Println(viper.GetString("redis.addr"))})
}func main() {InitViperLocal()server := gin.Default()server.Run(":8080")
}

程序运行结果:


http://www.ppmy.cn/ops/163452.html

相关文章

Python----Python爬虫(多线程,多进程,协程爬虫)

注意&#xff1a; 该代码爬取小说不久或许会失效&#xff0c;有时候该网站会被封禁&#xff0c;代码只供参考&#xff0c;不同小说不同网址会有差异 神印王座II皓月当空最新章节_神印王座II皓月当空全文免费阅读-笔趣阁 一、多线程爬虫 1.1、单线程爬虫的问题 爬虫通常被认为…

DeepSeek赋能Power BI:开启智能化数据分析新时代

在数据驱动决策的时代&#xff0c;数据分析工具的高效性与智能化程度成为决定企业竞争力的关键因素。Power BI作为一款功能强大的商业智能工具&#xff0c;深受广大数据分析师和企业用户的喜爱。而DeepSeek这一先进的人工智能技术的加入&#xff0c;更是为Power BI注入了新的活…

通过 Groq 后端加载Llama 模型,并调用Function call,也就是通过Groq 后端进行工具的绑定和调用

完整代码&#xff1a; import getpass import os from langchain.chat_models import init_chat_model from langchain_core.tools import tool from langchain_core.messages import HumanMessage, ToolMessage,SystemMessage# 如果没有设置 GROQ_API_KEY&#xff0c;则提示用…

如何停止Oracle expdp/impdp job

一、停止 expdp job举例 1.执行 expdp 命令 $ expdp rui/rui DIRECTORYdmp_dir dumpfilestudyfull_expdp.dmp FULLy logfilestudyfullexpdp.log job_nameexpdp_job2.查看在运行的作业名称 SQL> select job_name,state from dba_datapump_jobs; JOB_NAME …

0x03 http协议和分层架构

HTTP协议 简介 Hyper Text Transfer Protocol&#xff0c;超文本传输协议&#xff0c;规定了浏览器和服务器之间数据传输的规则 http协议基于TCP协议&#xff1a;面向连接&#xff0c;安全基于请求-响应模型&#xff1a;一次请求对应一次响应HTTP协议是无状态的协议&#xff…

颠覆NLP的魔法:深度解读Transformer架构及其核心组件

目录 颠覆NLP的魔法&#xff1a;深度解读Transformer架构及其核心组件 一、Transformer 架构概述 二、核心组件解析 1. Self-Attention&#xff08;自注意力机制&#xff09; 2. 位置编码&#xff08;Positional Encoding&#xff09; 3. 多头注意力&#xff08;Multi-Hea…

postman请求后端接受List集合对象

后端集合 post请求&#xff0c;即前端请求方式

C语言:51单片机 基础知识

一、单片机概述 单片机的组成及其特点 单片机是指在一块芯片上集成了CPU、ROM、RAM、定时器/计数器和多种I/O接口电路等&#xff0c;具有一定规模的微型计算机。 特点&#xff1a; 1、单片机的存储器以ROM、RAM严格分工。 2、采用面向控制的指令系统。 3、单片机的I/O口引脚通…