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

推荐订阅源

Attack and Defense Labs
Attack and Defense Labs
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园_首页
博客园 - 司徒正美
月光博客
月光博客
Apple Machine Learning Research
Apple Machine Learning Research
T
Tailwind CSS Blog
Jina AI
Jina AI
GbyAI
GbyAI
Y
Y Combinator Blog
罗磊的独立博客
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
P
Proofpoint News Feed
Last Week in AI
Last Week in AI
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
量子位
雷峰网
雷峰网
博客园 - 【当耐特】
H
Hackread – Cybersecurity News, Data Breaches, AI and More
The GitHub Blog
The GitHub Blog
S
Secure Thoughts
博客园 - 三生石上(FineUI控件)
Cyberwarzone
Cyberwarzone
NISL@THU
NISL@THU
J
Java Code Geeks
C
Cisco Blogs
人人都是产品经理
人人都是产品经理
Webroot Blog
Webroot Blog
腾讯CDC
博客园 - 叶小钗
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Troy Hunt's Blog
AI
AI
L
LangChain Blog
Know Your Adversary
Know Your Adversary
T
Tenable Blog
M
MIT News - Artificial intelligence
P
Privacy & Cybersecurity Law Blog
L
LINUX DO - 最新话题
Hugging Face - Blog
Hugging Face - Blog
F
Full Disclosure
P
Proofpoint News Feed
AWS News Blog
AWS News Blog
有赞技术团队
有赞技术团队
A
Arctic Wolf
Security Archives - TechRepublic
Security Archives - TechRepublic
S
Schneier on Security
Recent Commits to openclaw:main
Recent Commits to openclaw:main
W
WeLiveSecurity
The Cloudflare Blog

好好学习的郝

ClawdBot(OpenClaw)试用记录 编程辅助工具 Codex 入门篇 编程辅助工具 Claude Code 入门篇 Claude API 中转服务 Claude Relay Service LLM 接口管理和分发系统 New API 好好学Git:Git Submodule详解 编程辅助工具Cursor入门篇 好好学Golang:Golang问题记录 One API配置自定义渠道 FastAPI入门篇 好好学Docker:使用Docker安装配置AList 好好学Docker:容器指标查看工具ctop 好好学Docker:自建RustDesk Server 好好学Linux:Ubuntu18 升级到 Ubuntu22 好好学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)
}