当前位置: 首页 > news >正文

【Go】Go viper 配置模块

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")
}

程序运行结果:

相关文章:

【Go】Go viper 配置模块

1. 配置相关概念 在项目开发过程中&#xff0c;一旦涉及到与第三方中间件打交道就不可避免的需要填写一些配置信息&#xff0c;例如 MySQL 的连接信息、Redis 的连接信息。如果这些配置都采用硬编码的方式无疑是一种不优雅的做法&#xff0c;有以下缺陷&#xff1a; 不同环境…...

zabbix“专家坐诊”第277期问答

在线答疑:乐维社区 问题一 Q&#xff1a;这个怎么解决呢&#xff1f; A&#xff1a;缺少这个依赖。 Q&#xff1a;就一直装不上。 A&#xff1a;装 zabbix-agent2-7.0.0-releasel.el7.x86 64 需要前面提示的那个依赖才可以装。 问题二 Q&#xff1a;大佬&#xff0c;如果agen…...

大模型工程师学习日记(十一):FAISS 高效相似度搜索和密集向量聚类的库

Facebook AI Similarity Search (Faiss /Fez/) 是一个用于高效相似度搜索和密集向量聚类的库。它包含了在任意大小的向量集合中进行搜索的算法&#xff0c;甚至可以处理可能无法完全放入内存的向量集合。它还包含用于评估和参数调整的支持代码。 Faiss 官方文档&#xff1a;We…...

python学习第三天

条件判断 条件判断使用if、elif和else关键字。它们用于根据条件执行不同的代码块。 # 条件判断 age 18 if age < 18:print("你还是个孩子&#xff01;") elif age 18:print("永远十八岁&#xff01;") else:print("你还年轻&#xff01;")…...

深入解析 Svelte:下一代前端框架的革命

深入解析 Svelte&#xff1a;下一代前端框架的革命 1. Svelte 简介 Svelte 是一款前端框架&#xff0c;与 React、Vue 等传统框架不同&#xff0c;它采用 编译时&#xff08;Compile-time&#xff09; 方式来优化前端应用。它不像 React 或 Vue 依赖虚拟 DOM&#xff0c;而是…...

C++20 中位移位运算符的统一行为:深入解析与实践指南

文章目录 1. 位移位运算符的基础1.1 左移运算符&#xff08;<<&#xff09;1.2 右移运算符&#xff08;>>&#xff09; 2. C20 对位移位运算符的统一2.1 移位数量超出操作数位宽2.2 负数移位 3. 实践中的注意事项4. 示例代码5. 总结 在 C 的发展历程中&#xff0c;…...

Linux——基本指令

我们今天学习Linux最基础的指令 ls 指令 语法&#xff1a; ls [选项] [⽬录或⽂件] 功能&#xff1a;对于⽬录&#xff0c;该命令列出该⽬录下的所有⼦⽬录与⽂件。对于⽂件&#xff0c;将列出⽂件名以及其他信 息。 命令中的选项&#xff0c;一次可以传递多个 &#xff0c…...

MySql面试总结(二)

WHERE 子句优化 截至2024年7月,MySQL最新稳定版本是8.2,并不存在MySQL 8.4 。下面从常见的几个方面为你介绍 MySQL 8.x 中 WHERE 子句的优化方法: 1. 确保使用索引 原理:索引可以加快数据的查找速度,当 WHERE 子句中的条件列有索引时,MySQL 可以直接定位到符合条件的数…...

Pytorch中的主要函数

目录 一、torch.manual_seed(seed)二、torch.cuda.manual_seed(seed)三、torch.rand(*size, outNone, dtypeNone, layouttorch.strided, deviceNone, requires_gradFalse)四、给大家写一个常用的自动选择电脑cuda 或者cpu 的小技巧五、torch.version.cuda&#xff1b;torch.bac…...

Java实现大数据量导出报表

一、实现方式 在Java中&#xff0c;导出数据到Excel有多种方式&#xff0c;每种方式都有其优缺点&#xff0c;适用于不同的场景。以下是常见的几种方式及其特点&#xff1a; 1.1 Apache POI Apache POI 是 Java 中最流行的库&#xff0c;支持读写 Excel 文件&#xff08;包括…...

大语言模型 智能助手——既能生成自然语言回复,又能在必要时调用外部工具获取实时数据

示例代码&#xff1a; import json from langgraph.graph import Graph, END,StateGraph from langchain_core.utils.function_calling import convert_to_openai_function from langchain_community.tools.openweathermap import OpenWeatherMapQueryRun from langchain_core…...

PyTorch 系统教程:理解机器学习数据分割

数据分割是机器学习中的一个基本概念&#xff0c;它直接影响模型的性能和泛化。在本文中&#xff0c;我们将深入研究为什么数据分割在机器学习中很重要&#xff0c;并演示如何使用PyTorch有效地实现它。 理解数据分割 数据分割是将数据集划分为单独的组以进行训练、验证和测试…...

分水岭算法(Watershed Algorithm)教程:硬币分割实例

import cv2 import numpy as np# 1. 图像预处理 img cv2.imread("./water/water_coins.jpeg") gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, thresh cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV cv2.THRESH_OTSU) kernel np.ones((3, 3), np.int8)…...

【STM32项目实战系列】基于STM32G474的FDCAN驱动配置

前言&#xff1a;本周工作中用到了CANFD的驱动&#xff0c;由于以前都是用到的CAN2.0&#xff0c;所以过程并不是特别的顺利&#xff0c;所以中间遇到几个比较小的问题导致自己卡住了一段时间&#xff0c;特此记录一下并完全奉上自己的配置的源码。 1&#xff0c;CANFD配置与简…...

shell文本处理

shell文本处理 一、grep ​ 过滤来自一个文件或标准输入匹配模式内容。除了 grep 外&#xff0c;还有 egrep、fgrep。egrep 是 grep 的扩展&#xff0c;相当于 grep -E。fgrep 相当于 grep -f&#xff0c;用的比较少。 用法 grep [OPTION]... PATTERN [FILE]...支持的正则描述…...

如何利用客户端双向TLS认证保护云上应用安全

双向TLS(mTLS)通过要求服务器和客户端双方使用数字证书来验证彼此身份&#xff0c;从而扩展了传统TLS的安全性。常规的TLS只会验证服务器的身份(如大家的浏览器在验证网站时的场景)&#xff0c;而mTLS确保在任何数据交换发生之前&#xff0c;双方都对彼此持有信任。在本文中&am…...

nlp第十节——LLM相关

一、模型蒸馏技术 本质上是从一个大模型蒸馏出小模型&#xff0c;从小模型训练出来的概率分布&#xff08;如自回归模型预测下一个字的概率分布&#xff09;分别与大模型预测的概率分布和ground label求loss。与大模型预测的概率分布用KL散度求loss&#xff0c;与ground label用…...

T-SQL 语言基础: SQL 数据库对象元数据及配置信息获取

目录 介绍目录视图 获取表和架构名称获取列信息 信息架构视图 获取表信息获取列信息 系统存储过程和函数 获取对象列表获取对象详细信息获取约束信息获取数据库属性信息 总结引用 介绍 在 SQL 数据库管理中&#xff0c;获取数据库对象的元数据信息是至关重要的。元数据提供了…...

ue5 创建多列StreeView的方法与理解

创建StreeView的多列样式怎么就像是创建单行单列差不多&#xff1f;貌似就是在单行单列中加入了多列widget? 示例代码 DetailTabWidget #pragma once #include "TreeViewItemBase.h"class SDetailTabWidget : public SCompoundWidget {SLATE_BEGIN_ARGS(SDetailT…...

C# OnnxRuntime部署DAMO-YOLO香烟检测

目录 说明 效果 模型信息 项目 代码 下载 参考 说明 效果 模型信息 Model Properties ------------------------- --------------------------------------------------------------- Inputs ------------------------- name&#xff1a;input tensor&#xff1a;Floa…...

FPGA 51,基于 ZYNQ 7Z010 的 FPGA 高速路由转发加速系统架构设计(Xilinx ZYNQ-MINI 7Z010 CLG400 -1)

目录 前言 一、系统整体架构设计 1.1 设计目标与性能指标...

如何在PowerPoint中高效使用LaTeX进行数学公式排版

如何在PowerPoint中高效使用LaTeX进行数学公式排版 【免费下载链接】latex-ppt Use LaTeX in PowerPoint 项目地址: https://gitcode.com/gh_mirrors/la/latex-ppt 对于需要制作学术演示文稿的科研人员、教师和学生来说&#xff0c;在PowerPoint中排版复杂的数学公式一直…...

别再乱接线了!用PulseView+逻辑分析仪抓STM32 SPI波形,保姆级避坑指南

逻辑分析仪实战&#xff1a;精准捕获STM32 SPI波形的五大黄金法则 当你在调试STM32的SPI外设时&#xff0c;是否遇到过这样的困境&#xff1a;代码配置完全按照手册操作&#xff0c;但逻辑分析仪显示的波形却充满毛刺、数据残缺不全&#xff1f;这往往不是代码逻辑的问题&#…...

为什么我劝你放弃FLANN 1.9.2?聊聊源码编译那些坑与1.9.1版的真香选择

为什么FLANN 1.9.1才是开发者更明智的选择&#xff1a;深度解析编译陷阱与版本决策 在开源库的世界里&#xff0c;"最新版本"往往被默认为"最佳选择"&#xff0c;但FLANN 1.9.2却打破了这个常规认知。作为一名经历过无数次深夜调试的开发者&#xff0c;我必…...

别再只盯着AB相了!三引脚EC35编码器在智能面板上的应用与防误触设计

三引脚EC35编码器在智能面板设计中的创新应用与抗干扰实践 旋钮交互在智能家居和工业HMI领域从未失去它的魅力——当用户手指触碰到那个精致的金属环时&#xff0c;物理反馈带来的确定感是纯触控界面无法替代的。但传统AB相编码器的误触发问题长期困扰着产品设计师&#xff1a;…...

显卡选购指南:从显存、位宽到AI创作,2023年如何避开参数陷阱?

1. 显卡市场新动态&#xff1a;价格、定位与玩家选择的博弈最近显卡圈子里有点热闹&#xff0c;但这份热闹背后&#xff0c;更多是玩家们的困惑和观望。NVIDIA悄无声息地给RTX 4060 Ti加了个“大显存”的版本&#xff0c;价格直接上探到3899元&#xff0c;比8GB版贵出700块。这…...

2026年高清家用投影仪推荐:明基W系列领衔

一、前言&#xff1a;高清家用投影仪的核心&#xff0c;在于4K清晰度与真实色彩还原2026年的家用投影仪市场&#xff0c;“高清”早已不是简单的1080P&#xff0c;而是全面迈入4K UHD时代。但真正意义上的“高清家用投影仪”&#xff0c;不仅需要830万像素的真4K分辨率&#xf…...

MIPI CSI-2(3) 逃逸/LP模式 传输详解和波形图

专栏目录 MIPI CSI-2&#xff08;1&#xff09; D-PHY详细解析 MIPI CSI-2&#xff08;2&#xff09; HS模式 传输详解和波形图 MIPI CSI-2&#xff08;3&#xff09; 逃逸/LP模式 传输详解和波形图 逃逸模式时序 逃逸模式下lane始终通过LP-TX驱动&#xff0c;不要求有时钟&…...

离谱!上海交大一学生私吞 5000 奖金,还用豆包 P 假收据骗队友。网友:学历虽高但人品太低

①5 月 18 日&#xff0c;上海交大一则学生违纪通报冲上热搜&#xff0c;实锤了前几天网上曝光的一名学生侵占团队竞赛奖金、造假欺骗队友的恶劣行为。②在 2025 下半年&#xff0c;樊同学&#xff08;上交大智慧能源学院女生&#xff09;与 K 同学&#xff08;电院男生&#x…...

方法区内存回收机制与核心引用链深度剖析

在 Java 虚拟机&#xff08;JVM&#xff09;的内存管理体系中&#xff0c;方法区&#xff08;JDK 1.8 及以后具体实现为元空间 Metaspace&#xff09;的垃圾回收主要聚焦于两部分&#xff1a;废弃的常量池清理以及无用类的卸载&#xff08;Class Unloading&#xff09;。由于类…...