惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

好好学习的郝

ClawdBot(OpenClaw)试用记录 编程辅助工具 Codex 入门篇 LLM 接口管理和分发系统 New API Claude API 中转服务 Claude Relay Service 编程辅助工具 Claude Code 入门篇 好好学Git:Git Submodule详解 编程辅助工具Cursor入门篇 好好学Golang:Golang问题记录 One API配置自定义渠道 FastAPI入门篇 好好学Docker:使用Docker安装配置AList 好好学Docker:容器指标查看工具ctop 好好学Linux:Ubuntu18 升级到 Ubuntu22 好好学Docker:自建RustDesk Server 好好学Docker:使用Docker安装配置FileBrowser 邮箱配置中的SPF、DKIM、DMARC记录 One API 开发环境配置 LLM 接口管理和分发系统 One API 好好学K8S:K8S中的Leader Election机制
好好学Golang:Viper库
2024-10-06 · via 好好学习的郝

Viper是一个功能强大的Go语言配置管理库,旨在简化应用程序的配置处理。它支持多种配置文件格式,并能够从多种来源读取配置,适合现代应用程序的需求。Viper使得开发者能够专注于业务逻辑,而不必过多担心配置管理的问题。

参考文档:

2. Viper的特性

  • 多种配置格式支持: Viper可以读取JSON、TOML、YAML、HCL、INI、envfile和Java properties等格式的配置文件。
  • 环境变量支持: Viper可以从环境变量中读取配置。
  • 命令行参数: 通过与pflag等库结合,Viper能够处理命令行参数,并优先覆盖其他配置来源。
  • 实时监控: Viper支持实时监控配置文件的变动,并能在文件变化时自动重新加载配置。
  • 远程配置系统: Viper可以从远程配置系统(如etcd或Consul)读取和监控配置变化。
  • 默认值设置: 可以为不同的配置选项设置默认值,以确保应用在没有提供特定配置时仍能正常运行。
  • 别名系统: Viper允许为参数设置别名,以便在不破坏现有代码的情况下重命名参数。

3. Viper读取配置的优先级

Viper支持从多个数据源读取配置值,因此当同一个配置key在多个数据源有值时,Viper读取配置的优先级从高到低如下:

  • set:显示使用Set函数设置值
  • flag:命令行参数
  • env:环境变量
  • config:配置文件
  • key/value store:key/value存储系统,如 etcd
  • default:默认值

4. Viper读取环境变量

Viper读取环境变量,和读取配置文件中的变量,有很大不同:

  • Viper的key不区分大小写,内部会统一转为小写
  • 配置文件中的变量名,对应到环境变量中,全部大写
  • 环境变量不方便表示层级,因此在层级key和环境变量对应时,通常把点和中划线替换为下划线

5. 安装Viper

1
go get github.com/spf13/viper

6. Viper简单示例

以下是一个简单的示例,展示如何使用Viper加载YAML配置文件并从环境变量中覆盖某些值。

1、初始化一个golang项目

1
2
3
mkdir viper-demo && cd viper-demo
go mod init viper-demo
go get github.com/spf13/viper

2、创建配置文件 config.yaml

1
2
addr: 0.0.0.0
port: 8080

3、编写代码 main.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package main

import (
"fmt"
"github.com/spf13/viper"
)

type Config struct {
Addr string
Port int
}

func main() {

viper.SetConfigName("config")
viper.SetConfigType("yaml")
viper.AddConfigPath(".")


if err := viper.ReadInConfig(); err != nil {
panic(fmt.Errorf("无法读取配置文件: %s", err))
}


viper.AutomaticEnv()


config := Config{
Addr: viper.GetString("addr"),
Port: viper.GetInt("port"),
}

fmt.Printf("地址: %s, 端口: %d\n", config.Addr, config.Port)
}

4、运行 main.go

1
go run main.go

5、环境变量覆盖配置

1
2
3
export ADDR=127.0.0.1 

go run main.go

7. Viper层级配置示例

1、修改配置文件 config.yaml

1
2
3
http:
addr: 0.0.0.0
port: 8080

2、编写代码 main.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package main

import (
"fmt"
"strings"
"github.com/spf13/viper"
)

type Config struct {
Addr string
Port int
}

func main() {

viper.SetConfigName("config")
viper.SetConfigType("yaml")
viper.AddConfigPath(".")


if err := viper.ReadInConfig(); err != nil {
panic(fmt.Errorf("无法读取配置文件: %s", err))
}


viper.AutomaticEnv()

viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_"))


config := Config{
Addr: viper.GetString("http.addr"),
Port: viper.GetInt("http.port"),
}

fmt.Printf("地址: %s, 端口: %d\n", config.Addr, config.Port)
}

3、运行 main.go

1
go run main.go

4、环境变量覆盖配置

1
2
export HTTP_ADDR=127.0.0.1 
go run main.go

8. Viper层级配置示例进阶

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package main

import (
"fmt"
"strings"
"github.com/spf13/viper"
)

type Config struct {
HTTP struct {
Addr string
Port int
}
}

func main() {

viper.SetConfigName("config")
viper.SetConfigType("yaml")
viper.AddConfigPath(".")


if err := viper.ReadInConfig(); err != nil {
panic(fmt.Errorf("无法读取配置文件: %s", err))
}


viper.AutomaticEnv()

viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_"))


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

fmt.Printf("地址: %s, 端口: %d\n", config.HTTP.Addr, config.HTTP.Port)
}