最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談Golang如何使用Viper進(jìn)行配置管理

 更新時(shí)間:2023年06月27日 11:44:03   作者:Shawn27  
在Golang生態(tài)中,Viper是一個(gè)不錯(cuò)的開源配置管理框架,這篇文章主要為大家介紹了Golang如何使用Viper進(jìn)行配置管理,需要的可以參考一下

前言

應(yīng)用程序里要用到很多配置,比如監(jiān)聽端口、數(shù)據(jù)庫相關(guān)配置、緩存相關(guān)配置等。這些配置可能來自不同的源,最常見的是本地配置文件,也可以作為命令行參數(shù)或環(huán)境變量傳入,還可以托管在遠(yuǎn)程配置中心。同一項(xiàng)配置可能在多個(gè)不同的配置源中同時(shí)存在,如何處理優(yōu)先級?在程序運(yùn)行過程中,有些配置需要能夠動態(tài)更新,又該如何實(shí)現(xiàn)?配置的源、優(yōu)先級及動態(tài)更新,就是配置管理的內(nèi)容。

Golang生態(tài)中,Viper是一個(gè)不錯(cuò)的開源配置管理框架。

配置層級

Viper支持多種配置源,并處理了它們之間的優(yōu)先級問題,按優(yōu)先級從高到低的順序,層級如下:

  • 命令行參數(shù)
  • 環(huán)境變量
  • 本地配置文件
  • 遠(yuǎn)程配置文件
  • 默認(rèn)值

下面分別看一下Viper是如何支持這些配置源的。

0. 配置結(jié)構(gòu)

以如下的yaml格式配置文件來說明:

# myconfig.yaml
aaa: foo
xxx:
    bbb: bar
    ccc: 100

Viper在內(nèi)存中是用map類型來維護(hù)配置的,以配置名作為key、配置值作為Value。

為方便使用,我們可以定義如下的結(jié)構(gòu)體來接收配置:

package config
var Config config
type config struct {
    Aaa string
    Xxx struct {
        Bbb string
        Ccc uint
    }
}

1. 命令行參數(shù)

Viper提供了BindPFlags函數(shù)來綁定命令行參數(shù),以Cobra命令行框架為例,初始化代碼如下:

// 1. 根據(jù)需要定義命令行參數(shù)
pflags = rootCmd.PersistentFlags()
pflags.StringP("aaa", "a", "", "aaa's usage")
pflags.String("xxx.bbb", "", "xxx.bbb's usage")
pflags.Uint("xxx.ccc", 0, "xxx.ccc's usage")
// 2. Viper綁定命令行參數(shù)
viper.BindPFlags(pflags)

這樣就可以通過命令行參數(shù)來傳入相關(guān)配置:

// 參數(shù)aaa使用長參數(shù)格式
$ mycmd --aaa foo --xxx.bbb bar --xxx.ccc 100
// 參數(shù)aaa使用短參數(shù)格式
$ mycmd -a foo --xxx.bbb bar --xxx.ccc 100

2. 環(huán)境變量

Viper提供了AutomaticEnv函數(shù)來從環(huán)境變量中加載配置,示例代碼如下:

// 設(shè)置環(huán)境變量的前綴
viper.SetEnvPrefix("MYCMD")
// 將配置Key中的點(diǎn)號(.)和橫杠(-)替換為下劃線(_)
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_"))
// 從環(huán)境變量中讀取匹配的配置
viper.AutomaticEnv()

這樣就可以通過環(huán)境變量來傳入相關(guān)配置:

$ MYCMD_AAA=foo MYCMD_XXX_BBB=bar MYCMD_XXX_CCC=100 mycmd

3. 本地配置文件

Viper提供了從本地配置文件加載配置的方法,示例代碼如下:

// 在初始化cobra時(shí),將本地配置文件路徑定義為命令行參數(shù)
pflags.StringVarP(&cfgFile, "config", "c", "", "config file")
// 在初始化viper時(shí),設(shè)置本地配置文件路徑
viper.SetConfigFile(cfgFile)
// 讀取本地配置文件
if err := viper.ReadInConfig(); err != nil {
    log.Fatal(err)
}

這樣就可以通過本地配置文件來傳入相關(guān)配置:

// myconf.yaml為同目錄下的配置文件,內(nèi)容如上文所述
$ mycmd --config myconf.yaml

4. 遠(yuǎn)程配置文件

Viper還支持將配置文件托管在遠(yuǎn)程配置中心,如etcd,示例代碼如下:

// 注意:在實(shí)際項(xiàng)目中,以下參數(shù)也可以作為配置傳入
provider := "etcd3"
endpoint := "x.x.x.x:2379"
path := "/config/mycmd/myconf.yaml"
viper.AddRemoteProvider(provider, endpoint, path)
viper.SetConfigType("yaml")
if err := viper.ReadRemoteConfig(); err != nil {
    log.Println("Read remote config failed:", err)
}

只要將myconf.yaml配置文件上傳到etcd的指定路徑下,程序就可以遠(yuǎn)程讀取了。

$ cat myconf.yaml | etcdctl put /config/mycmd/myconf.yaml

5. 默認(rèn)值

Viper還支持設(shè)置默認(rèn)值,對于在以上所有源中都不存在的配置,將使用其默認(rèn)值,示例代碼如下:

viper.SetDefault("aaa", "foo")
viper.SetDefault("xxx.bbb", "bar")
viper.SetDefault("xxx.ccc", 100)

在所有配置源都加載后,我們可以將Viper配置裝載到配置結(jié)構(gòu)體變量中,方便使用:

if err := viper.Unmarshal(&config.Config); err != nil {
    log.Fatal("Viper unmarshal failed:", err)
}

配置動態(tài)更新

以上解決了靜態(tài)配置管理的問題,如何實(shí)現(xiàn)配置的動態(tài)更新呢?

配置的動態(tài)更新包括三個(gè)步驟:

  • 更新配置源中的配置
  • 更新內(nèi)存中的配置
  • 配置的動態(tài)生效

注意:如Viper官方文檔所提,Viper本身不是并發(fā)安全的,在實(shí)現(xiàn)配置動態(tài)更新時(shí),要注意采用鎖機(jī)制等方式來保證Viper并發(fā)讀寫的安全。

1. 更新配置源中的配置

Viper支持的配置源中,命令行參數(shù)、環(huán)境變量是在進(jìn)程啟動時(shí)一次性讀取的,不支持動態(tài)更新。本地配置文件和遠(yuǎn)程配置文件可以支持動態(tài)更新,直接修改配置文件即可。

2. 更新內(nèi)存中的配置

Viper支持監(jiān)聽本地配置文件的變化,同時(shí)允許注冊文件變化時(shí)的回調(diào)函數(shù),借助這個(gè)功能可以實(shí)現(xiàn)本地配置文件的動態(tài)更新,示意代碼如下:

viper.OnConfigChange(func(e fsnotify.Event) {
    // 回調(diào)函數(shù)
    // 可在此處更新內(nèi)存中的本地配置:
    // 1. 重新讀取本地配置:ReadInConfig
    // 2. 裝載到配置結(jié)構(gòu)體:Unmarshal
    // 注意:為Viper及配置結(jié)構(gòu)體加鎖
})
viper.WatchConfig()

對于遠(yuǎn)程配置文件,可以通過周期性地重新讀取來實(shí)現(xiàn)動態(tài)更新,示意代碼如下:

go func() {
    for {
        time.Sleep(time.Second * 10)
        // 周期為10s
        // 可在此處更新內(nèi)存中的遠(yuǎn)程配置:
        // 1. 重新讀取遠(yuǎn)程配置:WatchRemoteConfig
        // 2. 裝載到配置結(jié)構(gòu)體:Unmarshal
        // 注意:為Viper及配置結(jié)構(gòu)體加鎖
    }
}()

3. 配置的動態(tài)生效

不同配置的使用方式不同,動態(tài)生效方式也就不同,大概可以分為兩類:

  • 有些配置,每次使用時(shí)都是讀取最新的值,因此只要更新了內(nèi)存中的配置,就會即時(shí)生效
  • 有些配置,比如數(shù)據(jù)庫憑據(jù),可能需要重建連接池才能生效

在這里就不再細(xì)說了。

總結(jié)

本文介紹了在Golang中優(yōu)雅、靈活地實(shí)現(xiàn)配置管理的一種方式,涵蓋配置的源、優(yōu)先級及動態(tài)更新等內(nèi)容。重點(diǎn)說明了命令行參數(shù)、環(huán)境變量、本地配置文件、遠(yuǎn)程配置文件等多種配置源的實(shí)現(xiàn)方法,以及配置動態(tài)更新的實(shí)現(xiàn)思路。

以上就是淺談Golang如何使用Viper進(jìn)行配置管理的詳細(xì)內(nèi)容,更多關(guān)于Go Viper配置管理的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Golang微服務(wù)框架Kratos實(shí)現(xiàn)Kafka消息隊(duì)列的方法

    Golang微服務(wù)框架Kratos實(shí)現(xiàn)Kafka消息隊(duì)列的方法

    消息隊(duì)列是大型分布式系統(tǒng)不可缺少的中間件,也是高并發(fā)系統(tǒng)的基石中間件,所以掌握好消息隊(duì)列MQ就變得極其重要,在本文當(dāng)中,您將了解到:什么是消息隊(duì)列?什么是Kafka?怎樣在微服務(wù)框架Kratos當(dāng)中應(yīng)用Kafka進(jìn)行業(yè)務(wù)開發(fā),需要的朋友可以參考下
    2023-09-09
  • viper配置框架的介紹支持zookeeper的讀取和監(jiān)聽

    viper配置框架的介紹支持zookeeper的讀取和監(jiān)聽

    這篇文章主要介紹了viper配置框架的介紹支持zookeeper的讀取和監(jiān)聽,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-05-05
  • Golang time.Sleep()用法及示例講解

    Golang time.Sleep()用法及示例講解

    Go語言中的Sleep()函數(shù)用于在至少規(guī)定的持續(xù)時(shí)間d內(nèi)停止最新的go-routine,這篇文章主要介紹了Golang time.Sleep()用法及示例講解,需要的朋友可以參考下
    2023-02-02
  • goland配置自動注釋的實(shí)現(xiàn)

    goland配置自動注釋的實(shí)現(xiàn)

    本文主要介紹了goland配置自動注釋的實(shí)現(xiàn),文中通過圖文示例介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-08-08
  • MacOS下本地golang環(huán)境搭建詳細(xì)教程

    MacOS下本地golang環(huán)境搭建詳細(xì)教程

    這篇文章主要介紹了MacOS下本地golang環(huán)境搭建詳細(xì)教程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • Windows下在CMD下執(zhí)行Go出現(xiàn)中文亂碼的解決方法

    Windows下在CMD下執(zhí)行Go出現(xiàn)中文亂碼的解決方法

    在cmd下運(yùn)行g(shù)o程序或者是GOLAND的Terminal下運(yùn)行g(shù)o程序會出現(xiàn)中文亂碼的情況。本文就詳細(xì)的介紹下解決方法,具有一定的參考價(jià)值,感興趣的可以了解一下
    2021-12-12
  • Go語言到底有沒有引用傳參(對比 C++ )

    Go語言到底有沒有引用傳參(對比 C++ )

    這篇文章主要介紹了Go 到底有沒有引用傳參(對比 C++ ),需要的朋友可以參考下
    2017-09-09
  • Golang并發(fā)編程重點(diǎn)講解

    Golang并發(fā)編程重點(diǎn)講解

    這篇文章主要介紹了Golang并發(fā)編程,在許多環(huán)境中,實(shí)現(xiàn)對共享變量的正確訪問所需要的微妙之處使并發(fā)編程變得困難。Go鼓勵(lì)一種不同的方法,在這種方法中,共享值在通道中傳遞,實(shí)際上,從不由單獨(dú)的執(zhí)行線程主動共享
    2023-04-04
  • Go 語言json.Unmarshal 遇到的小問題(推薦)

    Go 語言json.Unmarshal 遇到的小問題(推薦)

    這篇文章主要介紹了 Go 語言json.Unmarshal 遇到的小問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • 使用Go語言生成二維碼并在命令行中輸出

    使用Go語言生成二維碼并在命令行中輸出

    二維碼(QR code)是一種矩陣條碼的標(biāo)準(zhǔn),廣泛應(yīng)用于商業(yè)、移動支付和數(shù)據(jù)存儲等領(lǐng)域,在開發(fā)過程中,我們可能需要在命令行中顯示二維碼,這可以幫助我們快速生成和分享二維碼信息,本文將介紹如何使用Go語言生成二維碼并在命令行中輸出,需要的朋友可以參考下
    2023-11-11

最新評論

中宁县| 襄垣县| 临西县| 高唐县| 元谋县| 江城| 七台河市| 绥阳县| 西吉县| 丰原市| 大石桥市| 保康县| 满洲里市| 司法| 定襄县| 周至县| 南丹县| 郴州市| 滁州市| 深泽县| 苗栗市| 珠海市| 车致| 张家界市| 吉林省| 泸水县| 连江县| 微博| 广饶县| 冀州市| 镇平县| 丹凤县| 威海市| 水富县| 金坛市| 韶山市| 雅安市| 班玛县| 东至县| 东方市| 香格里拉县|