Go语言项目中使用Viper获取配置信息详解

2024-04-18 0 527
目录
  • 从配置文件中获取配置
  • 从环境变量中获取配置
  • 其他

Viper是Go应用的完整配置解决方案,它能处理所有类型的配置需求和配置格式,支持:

  • 设置默认值。
  • 读取JSON、TOML、YAML、HCL、envfile和Java属性配置文件。
  • 实时观察和重新读取配置(可选)。
  • 读取环境变量。
  • 从远程配置系统(etcd或Consul)读取配置,并观察其变化。
  • 从命令行标志读取配置。
  • 从缓冲区读取配置。
  • 设置显式值。

Viper的优先级顺序是:显式调用Set > 命令行标志 > 环境变量 > 配置文件 > 键/值 存储(etcd或Consul) > 默认值。

本文主要记录从yaml文件、环境变量中获取配置。

使用的go的版本和viper的版本如下:

go 1.20
github.com/spf13/viper v1.18.2

从配置文件中获取配置

执行以下指令初始化项目:

go mod init github.com/rengmo/practicego

执行以下语句安装viper包:

go get github.com/spf13/viper

创建yaml文件config/dev.yaml,内容如下:

redis:
host: localhost
port: 6379
user: # 本地redis的用户名为空
password: abc123
db: 0

创建Go文件infrastructure/config.go,内容如下:

package config

import (
\”fmt\”

\”github.com/spf13/viper\”
)

func init() {
// 设置配置文件的名字
viper.SetConfigName(\”dev\”)
// 设置文件的格式
viper.SetConfigType(\”yaml\”)
// 设置查找配置文件的路径为当前路径 . 表示项目的工作目录,也就是main.go同级的那个目录
viper.AddConfigPath(\”./config\”)

// 读取配置文件中的数据到viper中
err := viper.ReadInConfig()
if err != nil {
panic(err)
}
// 从viper中获取配置数据
redisPort := viper.Get(\”redis.port\”)
fmt.Printf(\”redisPort: %v \\n\”, redisPort) // 打印结果:redisPort: 6379
}

还可以使用GetInt()、GetString()等方法,获取指定类型的数据,viper.GetString("redis.port")就是获取字符串类型的数据。

创建main.go文件,内容如下:

package main

import (
_ \”github.com/rengmo/practicego/infrastructure\”
)

func main() {

}

运行代码,会打印出获取到的端口号。

// 设置配置文件的名字
viper.SetConfigName(\”dev\”)
// 设置文件的格式
viper.SetConfigType(\”yaml\”)
// 设置查找配置文件的路径为当前路径 . 表示项目的工作目录,也就是main.go同级的那个目录
viper.AddConfigPath(\”./config\”)

换成:

// 设置配置文件的路径
viper.SetConfigFile(\”./config/dev.yaml\”)

同样能取到配置文件中的数据。

除了使用Get方法viper.Get("redis.port")获取配置数据,还可以将配置数据反序列化成Go对象。

func init() {

var config *Config
err = viper.Unmarshal(&config)
if err != nil {
panic(err)
}
redisConfig := config.Redis
fmt.Printf(\”redisConfig %+v\\n\”, redisConfig)
// 打印的结果:redisConfig {Host:localhost Port:6379 User: Password:abc123 DB:0}
}

type Config struct {
Redis RedisConfig
}

type RedisConfig struct {
Host string
Port int
User string
Password string
DB int
}

Viper对于配置项的键是不区分大小写的,比如把yaml文件中的键改成首字母大写:

Redis:
Host: localhost
Port: 6379

使用viper.Get("redis.port")一样能获取到配置的值,使用viper.Get("REDIS.PORT")同样能获取配置的值。

从环境变量中获取配置

AutomaticEnv会检查环境变量中是否有和已经存在的键匹配的环境变量,如果有,就会把环境变量加载到viper中。

// AutomaticEnv makes Viper check if environment variables match any of the existing keys
// (config, default or flags). If matching env vars are found, they are loaded into Viper.
func AutomaticEnv() { v.AutomaticEnv() }

先在终端执行指令添加环境变量: export env=PROD,然后在终端执行go run .。

光看这个函数名称,是自动将环境变量添加到viper中的意思,那么执行下面的语句应该就能获取环境变量,但是无效:

viper.AutomaticEnv()
env := viper.Get(\”env\”)
fmt.Println(\”env: \”, env) // env: <nil>

根据函数注释,需要确认viper中是否已经有对应的键,那么执行下面的语句应该就能获取环境变量,但是依然无效:

viper.SetDefault(\”env\”, \”DEV\”)
viper.AutomaticEnv()
env := viper.Get(\”env\”)
fmt.Println(\”env: \”, env) // env: DEV

找了一下源码,判断键是否存在的地方使用了envkeys, exists := v.env[lcaseKey],而BindEnv方法中有设置v.env:

func (v *Viper) BindEnv(input …string) error {
if len(input) == 0 {
return fmt.Errorf(\”missing key to bind to\”)
}

key := strings.ToLower(input[0])

if len(input) == 1 {
v.env[key] = append(v.env[key], v.mergeWithEnvPrefix(key))
} else {
v.env[key] = append(v.env[key], input[1:]…)
}

return nil
}

所以需要这样使用:

viper.BindEnv(\”env\”, \”DEV\”)
viper.AutomaticEnv()
env := viper.Get(\”env\”)
fmt.Println(\”env: \”, env) // env: PROD

要注意在比较过程中,Viper会把key转换成大写字母与环境变量进行比较,所以环境变量的名称必须为大写,不能这样设置环境变量:export env=PROD,必须这样设置环境变量:export ENV=PROD。

其他

如果是使用编辑器来运行代码,需要在编辑器中设置环境变量,我用的是VSCode编辑器,所以是在launch.json中添加了环境变量:

{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
\”version\”: \”0.2.0\”,
\”configurations\”: [
{
\”name\”: \”Launch Package\”,
\”type\”: \”go\”,
\”request\”: \”launch\”,
\”mode\”: \”auto\”,
\”program\”: \”${workspaceFolder}\”,
\”env\”: {
\”env\”: \”PROD\”
}
}
]
}

序列化和反序列化时,可以使用 mapstructure指定键的名称。

比如yaml文件内容:

mysql:
host: localhost
port: 3306
user: root
password: 666666Aa_
db_name: practicego

go文件内容:

type Config struct {
Redis RedisConfig
MySQL MySQLConfig
Priority string
}

type MySQLConfig struct {
Host string
Port int
User string
Password string
DBName string `mapstructure:\”db_name\”`
}

func init() {
viper.SetConfigFile(\”./config/dev.yaml\”)
err := viper.ReadInConfig()
if err != nil {
panic(err)
}

var config *Config
err = viper.Unmarshal(&config)
if err != nil {
panic(err)
}

mysqlConfig := config.MySQL
fmt.Printf(\”mysqlConfig %+v\\n\”, mysqlConfig)
}

以上就是Go语言项目中使用Viper获取配置信息详解的详细内容,更多关于Go Viper获取配置信息的资料请关注悠久资源网其它相关文章!

您可能感兴趣的文章:

  • 详解如何使用Go的Viper来解析配置信息
  • 使用Viper处理Go应用程序的配置方法
  • Go viper读取配置文件的示例详解
  • Go一站式配置管理工具Viper的使用教程
  • 浅谈Golang如何使用Viper进行配置管理
  • Golang配置管理库 Viper的教程详解
  • Golang使用第三方包viper读取yaml配置信息操作

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悠久资源 Golang Go语言项目中使用Viper获取配置信息详解 https://www.u-9.cn/jiaoben/golang/187297.html

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务