欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go語言項目中使用Viper獲取配置信息詳解

 更新時間:2024年04月02日 08:15:24   作者:仍沫  
Viper是Go應(yīng)用的完整配置解決方案,它能處理所有類型的配置需求和配置格式,這篇文章主要介紹了Go項目中使用Viper獲取配置信息,需要的可以參考下

Viper是Go應(yīng)用的完整配置解決方案,它能處理所有類型的配置需求和配置格式,支持:

  • 設(shè)置默認(rèn)值。
  • 讀取JSON、TOML、YAML、HCL、envfile和Java屬性配置文件。
  • 實時觀察和重新讀取配置(可選)。
  • 讀取環(huán)境變量。
  • 從遠程配置系統(tǒng)(etcd或Consul)讀取配置,并觀察其變化。
  • 從命令行標(biāo)志讀取配置。
  • 從緩沖區(qū)讀取配置。
  • 設(shè)置顯式值。

Viper的優(yōu)先級順序是:顯式調(diào)用Set > 命令行標(biāo)志 > 環(huán)境變量 > 配置文件 > 鍵/值 存儲(etcd或Consul) > 默認(rèn)值。

本文主要記錄從yaml文件、環(huán)境變量中獲取配置。

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

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

從配置文件中獲取配置

執(zhí)行以下指令初始化項目:

go mod init github.com/rengmo/practicego

執(zhí)行以下語句安裝viper包:

go get github.com/spf13/viper

創(chuàng)建yaml文件config/dev.yaml,內(nèi)容如下:

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

創(chuàng)建Go文件infrastructure/config.go,內(nèi)容如下:

package config

import (
	"fmt"

	"github.com/spf13/viper"
)

func init() {
	// 設(shè)置配置文件的名字
	viper.SetConfigName("dev")
	// 設(shè)置文件的格式
	viper.SetConfigType("yaml")
	// 設(shè)置查找配置文件的路徑為當(dāng)前路徑 . 表示項目的工作目錄,也就是main.go同級的那個目錄
	viper.AddConfigPath("./config")

	// 讀取配置文件中的數(shù)據(jù)到viper中
	err := viper.ReadInConfig()
	if err != nil {
		panic(err)
	}
	// 從viper中獲取配置數(shù)據(jù)
	redisPort := viper.Get("redis.port")
	fmt.Printf("redisPort: %v \n", redisPort) // 打印結(jié)果:redisPort: 6379 
}

還可以使用GetInt()、GetString()等方法,獲取指定類型的數(shù)據(jù),viper.GetString("redis.port")就是獲取字符串類型的數(shù)據(jù)。

創(chuàng)建main.go文件,內(nèi)容如下:

package main

import (
	_ "github.com/rengmo/practicego/infrastructure"
)

func main() {

}

運行代碼,會打印出獲取到的端口號。

	// 設(shè)置配置文件的名字
	viper.SetConfigName("dev")
	// 設(shè)置文件的格式
	viper.SetConfigType("yaml")
	// 設(shè)置查找配置文件的路徑為當(dāng)前路徑 . 表示項目的工作目錄,也就是main.go同級的那個目錄
	viper.AddConfigPath("./config")

換成:

// 設(shè)置配置文件的路徑
viper.SetConfigFile("./config/dev.yaml")

同樣能取到配置文件中的數(shù)據(jù)。

除了使用Get方法viper.Get("redis.port")獲取配置數(shù)據(jù),還可以將配置數(shù)據(jù)反序列化成Go對象。

func init() {
  ...
	var config *Config
	err = viper.Unmarshal(&config)
	if err != nil {
		panic(err)
	}
	redisConfig := config.Redis
	fmt.Printf("redisConfig %+v\n", redisConfig) 
  // 打印的結(jié)果: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對于配置項的鍵是不區(qū)分大小寫的,比如把yaml文件中的鍵改成首字母大寫:

Redis:
  Host: localhost
  Port: 6379

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

從環(huán)境變量中獲取配置

AutomaticEnv會檢查環(huán)境變量中是否有和已經(jīng)存在的鍵匹配的環(huán)境變量,如果有,就會把環(huán)境變量加載到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() }

先在終端執(zhí)行指令添加環(huán)境變量: export env=PROD,然后在終端執(zhí)行go run .。

光看這個函數(shù)名稱,是自動將環(huán)境變量添加到viper中的意思,那么執(zhí)行下面的語句應(yīng)該就能獲取環(huán)境變量,但是無效:

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

根據(jù)函數(shù)注釋,需要確認(rèn)viper中是否已經(jīng)有對應(yīng)的鍵,那么執(zhí)行下面的語句應(yīng)該就能獲取環(huán)境變量,但是依然無效:

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

找了一下源碼,判斷鍵是否存在的地方使用了envkeys, exists := v.env[lcaseKey],而BindEnv方法中有設(shè)置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轉(zhuǎn)換成大寫字母與環(huán)境變量進行比較,所以環(huán)境變量的名稱必須為大寫,不能這樣設(shè)置環(huán)境變量:export env=PROD,必須這樣設(shè)置環(huán)境變量:export ENV=PROD。

其他

如果是使用編輯器來運行代碼,需要在編輯器中設(shè)置環(huán)境變量,我用的是VSCode編輯器,所以是在launch.json中添加了環(huán)境變量:

{
    // 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文件內(nèi)容:

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

go文件內(nèi)容:

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獲取配置信息詳解的詳細內(nèi)容,更多關(guān)于Go Viper獲取配置信息的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Golang 標(biāo)準(zhǔn)庫 tips之waitgroup詳解

    Golang 標(biāo)準(zhǔn)庫 tips之waitgroup詳解

    本篇文章給大家介紹Golang 標(biāo)準(zhǔn)庫 tips之waitgroup的相關(guān)知識,包括使用 channel 實現(xiàn) WaitGroup 的功能介紹,感興趣的朋友跟隨小編一起看看吧
    2021-07-07
  • 更高效的GoLevelDB:shardingdb實現(xiàn)分片和并發(fā)讀寫操作

    更高效的GoLevelDB:shardingdb實現(xiàn)分片和并發(fā)讀寫操作

    這篇文章主要介紹了更高效的GoLevelDB:shardingdb實現(xiàn)分片和并發(fā)讀寫操作的相關(guān)資料,需要的朋友可以參考下
    2023-09-09
  • 使用go net實現(xiàn)簡單的redis通信協(xié)議

    使用go net實現(xiàn)簡單的redis通信協(xié)議

    本文主要介紹了go net實現(xiàn)簡單的redis通信協(xié)議,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • 關(guān)于golang test緩存問題

    關(guān)于golang test緩存問題

    這篇文章主要介紹了關(guān)于golang test緩存問題,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-09-09
  • 解決Goland 提示 Unresolved reference 錯誤的問題

    解決Goland 提示 Unresolved reference 錯誤的問題

    這篇文章主要介紹了解決Goland 提示 Unresolved reference 錯誤的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • 深入理解Go語言中接口的使用

    深入理解Go語言中接口的使用

    在現(xiàn)代編程語言中,接口是不可或缺的一個重要特性,這篇文章將為大家詳細介紹Go語言中的接口,從而能夠更好得使用Go語言,需要的可以參考一下
    2023-06-06
  • Golang學(xué)習(xí)筆記(三):控制流

    Golang學(xué)習(xí)筆記(三):控制流

    這篇文章主要介紹了Golang學(xué)習(xí)筆記(三):控制流,本文講解了IF、FOR、SWITCH、goto、break、continue等控制流語句的使用實例,需要的朋友可以參考下
    2015-05-05
  • golang基礎(chǔ)之字符串與int、int64類型互相轉(zhuǎn)換

    golang基礎(chǔ)之字符串與int、int64類型互相轉(zhuǎn)換

    這篇文章主要給大家介紹了關(guān)于golang基礎(chǔ)之字符串與int、int64類型互相轉(zhuǎn)換的相關(guān)資料,在Go語言中string轉(zhuǎn)int是一項常見的操作,需要的朋友可以參考下
    2023-07-07
  • Go語言異步API設(shè)計的扇入扇出模式詳解

    Go語言異步API設(shè)計的扇入扇出模式詳解

    這篇文章主要為大家介紹了Go語言異步API設(shè)計的扇入扇出模式示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • 圖文詳解Go程序如何編譯并運行起來的

    圖文詳解Go程序如何編譯并運行起來的

    Go語言這兩年在語言排行榜上的上升勢頭非常猛,Go語言雖然是靜態(tài)編譯型語言,但是它卻擁有腳本化的語法,下面這篇文章主要給大家介紹了關(guān)于Go程序如何編譯并運行起來的相關(guān)資料,需要的朋友可以參考下
    2024-05-05

最新評論