[Golang] Viper原理以及详细使用案例

在这里插入图片描述

文章目录

  • 什么是 Viper?
  • 基础配置
    • 引入依赖:
    • 动态监听原理分析:
    • 监听原理分析
  • Config.yaml文件配置
  • Viper文件配置

什么是 Viper?

介绍:用于处理配置文件中解析和读取配置文件
优点:支持多种配置格式,json,yaml 等等
作用:配置文件解析和读取 默认值支持 环境变量支持 命令行标志支持 配置监听和热加载

基础配置

引入依赖:

go get github.com/spf13/viper

读取文件方法:

    viper.SetConfigFile("haha")      //配置文件名,不需要后缀viper.SetConfigType("yaml")      //设置配置文件格式viper.AddConfigPath("../config") //查找路径err := viper.ReadInConfig()      //读取配置文件

读取文件方法二:

 	viper.SetConfigFile("./config/config.yaml")err := viper.ReadInConfig()

动态监听原理分析:

//监听配置文件
viper.WatchConfig()
//监听是否更改配置文件
viper.OnConfigChange(func(e fsnotify.Event) {fmt.Println("配置文件被人修改了...")err := viper.Unmarshal(&Conf)if err != nil {panic(fmt.Errorf("配置文件修改以后,报错啦,err:%v", err))}
})

监听原理分析

分析WatchConfig()方法
// 监听文件变化
func (v *Viper) WatchConfig() {//开启一个协程  相当于开启一个任务initWG := sync.WaitGroup{}initWG.Add(1)go func() {//创建一个文件监听器watcher, err := newWatcher()if err != nil {v.logger.Error(fmt.Sprintf("failed to create watcher: %s", err))os.Exit(1)}defer watcher.Close()// we have to watch the entire directory to pick up renames/atomic saves in a cross-platform way//获得配置文件名filename, err := v.getConfigFile()if err != nil {v.logger.Error(fmt.Sprintf("get config file: %s", err))initWG.Done()return}//规范化配置文件路径信息configFile := filepath.Clean(filename)configDir, _ := filepath.Split(configFile)//获得文件的真实路径realConfigFile, _ := filepath.EvalSymlinks(filename)//再开启一个协程 去监听监听器的状态eventsWG := sync.WaitGroup{}eventsWG.Add(1)go func() {for {select {//监听监听器的事务case event, ok := <-watcher.Events:if !ok { // 'Events' channel is closedeventsWG.Done()return}currentConfigFile, _ := filepath.EvalSymlinks(filename)// we only care about the config file with the following cases:// 1 - if the config file was modified or created// 2 - if the real path to the config file changed (eg: k8s ConfigMap replacement)//判断文件是否修改,创建 配置文件的真实路径是否发生变化if (filepath.Clean(event.Name) == configFile &&(event.Has(fsnotify.Write) || event.Has(fsnotify.Create))) ||(currentConfigFile != "" && currentConfigFile != realConfigFile) {realConfigFile = currentConfigFile//变化之后 重新进行文件读取err := v.ReadInConfig()if err != nil {v.logger.Error(fmt.Sprintf("read config file: %s", err))}//调用回调函数去重新将内容写进结构体中if v.onConfigChange != nil {v.onConfigChange(event)}} else if filepath.Clean(event.Name) == configFile && event.Has(fsnotify.Remove) {eventsWG.Done()return}case err, ok := <-watcher.Errors:if ok { // 'Errors' channel is not closedv.logger.Error(fmt.Sprintf("watcher error: %s", err))}eventsWG.Done()return}}}()//如果发生文件找不到或者监听过程中出错就会退出内外两层协程,然后监听停止watcher.Add(configDir)initWG.Done()   // done initializing the watch in this go routine, so the parent routine can move on...eventsWG.Wait() // now, wait for event loop to end in this go-routine...}()initWG.Wait() // make sure that the go routine above fully ended before returning
}

同时通过mapstructure将配置文件中的信息(键值对)映射到结构体中,实现随时拿取

Config.yaml文件配置

mode: "dev"
port: 8080log:level: "debug"filename: "./log/logfile.log"max_size: 1000max_age: 3600max_backups: 5mysql:host: localhostport: 3306user: rootpassword: rootdb: librarymax_open_conns: 100max_idle_conns: 20redis:host: 127.0.0.1port: 6379db: 0

Viper文件配置

package configimport ("fmt""github.com/fsnotify/fsnotify""github.com/spf13/viper"
)var Conf = new(LibraryConfig)type MysqlConfig struct {Host         string `mapstructure:"host"`User         string `mapstructure:"user"`Password     string `mapstructure:"password"`DB           string `mapstructure:"db"`Port         int    `mapstructure:"port"`MaxOpenConns int    `mapstructure:"max_open_conns"`MaxIdleConns int    `mapstructure:"max_idle_conns"`
}
type RedisConfig struct {Host         string `mapstructure:"host"`Port         int    `mapstructure:"port"`DB           int    `mapstructure:"db"`Password     string `mapstructure:"password"`PollSize     int    `mapstructure:"PollSize"`MinIdleConns int    `mapstructure:"min_idle_cons"`
}
type LogConfig struct {Level      string `mapstructure:"level"`FileName   string `mapstructure:"filename"`MaxSize    int    `mapstructure:"max_size"`MaxAge     int    `mapstructure:"max_age"`MaxBackUps int    `mapstructure:"max_backups"`
}type LibraryConfig struct {Mode         string `mapstructure:"mode"`Port         int    `mapstructure:"port"`*LogConfig   `mapstructure:"log"`*MysqlConfig `mapstructure:"mysql"`*RedisConfig `mapstructure:"redis"`
}func Init() error {//加载配置文件位置viper.SetConfigFile("./config/config.yaml")//监听配置文件viper.WatchConfig()//监听是否更改配置文件viper.OnConfigChange(func(e fsnotify.Event) {fmt.Println("配置文件被人修改了...")err := viper.Unmarshal(&Conf)if err != nil {panic(fmt.Errorf("配置文件修改以后,报错啦,err:%v", err))}})// 读取配置文件内容err := viper.ReadInConfig()if err != nil {panic(fmt.Errorf("ReadInConfig failed,err:%v", err))}//将配置文件内容写入到Conf结构体if err1 := viper.Unmarshal(&Conf); err1 != nil {panic(fmt.Errorf("unmarshal data to Conf failed,err:%v", err))}return nil
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/8839.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

新老联手,火花四溅?大众汽车与小鹏汽车达成长期合作框架协议

7 月 26 日资讯&#xff0c;大众汽车宣布与小鹏汽车达成长期合作框架协议&#xff0c;并在官网中正式宣布&#xff0c;大众是老牌油车领军代表&#xff0c;小鹏则是新势力中的佼佼者&#xff0c;新老强强联手&#xff0c;又会碰撞出怎样的火花呢&#xff1f; 现阶段大众计划与…

Postman学习之常用断言

什么是断言&#xff1f; 断言——就是结果中的特定属性或值与预期做对比&#xff0c;如果一致&#xff0c;则用例通过&#xff0c;如果不一致&#xff0c;断言失败&#xff0c;用例失败。断言&#xff0c;是一个完整测试用例所不可或缺的一部分&#xff0c;没有断言的测试用例…

leetcode每日一练-第98题- 验证二叉搜索树

一、思路 因为要验证多个节点是否是二叉搜索树,因此使用递归 二、解题方法 设计一个递归函数 helper(root, lower, upper) 来递归判断&#xff0c;函数表示考虑以 root 为根的子树&#xff0c;判断子树中所有节点的值是否都在 (l,r)的范围内&#xff08;注意是开区间&#x…

git配置

git查看配置&#xff1a;git config --global --list git配置&#xff1a; git config --global user.name "yumlu" git config --global user.email "yumlucisco.com" git config --global core.editorvim git权限&#xff0c;添加密钥&#xff1a; …

工厂方法模式——多态工厂的实现

1、简介 1.1、概述 在工厂方法模式中&#xff0c;不再提供一个统一的工厂类来创建所有的产品对象&#xff0c;而是针对不同的产品提供不同的工厂&#xff0c;系统提供一个与产品等级结构对应的工厂等级结构。 1.2、定义 工厂方法模式&#xff08;Factory Method Pattern&am…

Filebeat学习笔记

Filebeat基本概念 简介 Filebeat是一种轻量级日志采集器&#xff0c;内置有多种模块&#xff08;auditd、Apache、Nginx、System、MySQL等&#xff09;&#xff0c;针对常见格式的日志大大简化收集、解析和可视化过程&#xff0c;只需一条命令即可。之所以能实现这一点&#…

设计模式原则

1、设计模式七大原则 1.1 设计模式的目的 编写软件过程中&#xff0c;程序员面临着来自 耦合性&#xff0c;内聚性以及可维护性&#xff0c;可扩展性&#xff0c;重用性&#xff0c;灵活性 等多方面的挑战&#xff0c;设计模式是为了让程序(软件)&#xff0c;具有更好 代码重…

Mkdocs中利用Js实现大小圈鼠标拖动样式

在docs/javascripts/extra.js下复制粘贴&#xff1a; var CURSOR;Math.lerp (a, b, n) > (1 - n) * a n * b;const getStyle (el, attr) > {try {return window.getComputedStyle? window.getComputedStyle(el)[attr]: el.currentStyle[attr];} catch (e) {}return …

k8s核心概念

一、集群架构与组件 1&#xff0c;相关组件 【1】 master node三个组件 k8s的控制节点&#xff0c;对集群进行调度管理&#xff0c;接受集群外用户去集群操作请求master node 组成&#xff08;四个组件&#xff09;&#xff1a;控制面 API Server&#xff1a;通信kube-Sche…

大模型的淘金时代,HPE给出了一份智能经济“奇点”攻略

进入2023年&#xff0c;ChatGPT引发了一个新的AI时代——大模型时代。陆奇说&#xff1a;“我已经跟不上大模型时代的狂飙速度了&#xff01;”大模型引发了AI产业整体升级换代&#xff0c;各种大模型层出不穷&#xff0c;科技公司纷纷入局&#xff0c;AI创业公司再次雨后春笋般…

【LeetCode】79.单词搜索

题目 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构成&#xff0c;其中“相邻”单元格是那些水平相邻或…

LabVIEW开发环境试验箱控制器

LabVIEW开发环境试验箱控制器 环境或气候试验箱是一种外壳&#xff0c;用于模拟各种材料&#xff08;包括工业产品、生物物质、复合材料、电子设备和航空航天部件&#xff09;的特定环境条件&#xff0c;并评估调节对这些材料的影响。 环境试验箱&#xff08;ETC&#xff09;…

08.计算机网络——其他重要协议和技术

文章目录 DNSICMPNAT代理服务器 DNS DNS是一整套从域名映射到IP的系统 ​ TCP/IP中使用IP地址和端口号来确定网络上的一台主机的一个程序&#xff0c;但是IP地址不方便记忆&#xff0c;于是人们发明域名&#xff0c;其本质是一个字符串&#xff0c;映射了它和IP地址的关系。 …

【iOS】—— RunLoop和多线程相关问题总结

RunLoop 1. 讲讲RunLoop&#xff0c;项目中有用到过吗&#xff1f; RunLoop 的基本作用&#xff1a;保持程序的持续运行&#xff0c;节省 CPU 的资源&#xff0c;提高程序的性能 &#xff08; 没有事情&#xff0c;就请休眠&#xff0c;不要功耗。有事情&#xff0c;就处理&a…

【JavaSE】运算符

【本节目标】 1. 熟练掌握各种运算符 这部分内容和C语言的位运算相似&#xff0c;可以参考这篇文章&#xff1a;【C语言】操作符详解 目录 1. 什么是运算符 2. 算术运算符 3. 关系运算符 4. 逻辑运算符 5. 位运算符 6. 移位运算(了解) 7. 条件运算符 1. 什么是运算符 …

day31贪心算法 用最少数量的箭引爆气球 和无重叠区间

题目描述 题目分析&#xff1a; x轴向上射箭&#xff0c;12一支&#xff0c;重叠的需要一支&#xff0c;3-8一支&#xff0c;7-16一支 返回2&#xff1b; 就是让重叠的气球尽量在一起&#xff0c;局部最优&#xff1b;用一支弓箭&#xff0c;全局最优就是最少弓箭&#xff1b…

SQL ORDER BY 关键字

ORDER BY 关键字用于对结果集进行排序。 ORDER BY 关键字用于对结果集按照一个列或者多个列进行排序。 ORDER BY 关键字默认按照升序对记录进行排序。如果需要按照降序对记录进行排序&#xff0c;您可以使用 DESC 关键字。 ORDER BY 子句后面的列名指示按哪些列进行排序。如…

如何才能做Cox呢?今天带来Cox回归分析步骤详解

Cox回归是生存分析中运用最多的一个模型&#xff0c;又称为比例风险回归模型(proportional hazards model)。是由英国统计学家D.R.Cox在1962年提出的&#xff0c;为了表示对他的尊敬&#xff0c;所以大家以他的名字命名这个模型。这是一种半参数回归模型&#xff0c;以结局和生…

数据结构【绪论】

数据结构入门级 第一章绪论 什么是数据结构&#xff1f;什么是数据类型&#xff1f; 程序数据结构算法 一、基本概念&#xff1a; 数据&#xff1a;指所有能被计算机处理的&#xff0c;无论图、文字、符号等。数据元素&#xff1a;数据的基本单位&#xff0c;通常作为整体考…

快速上手Webpack打包指南:用简单的步骤掌握Webpack的使用技巧

目录 概念&#xff1a;1. webpack 打包简介1.0 多个 JS 文件打包&#xff1a;1.1 webpack 数组形式1.2 webpack 对象形式 总结 Webpack的打包过程可以总结为以下几个步骤&#xff1a; 1.入口点配置&#xff1a;在Webpack的配置文件中&#xff0c;我们需要指定一个或多个入口点…