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

Go中的應用配置管理詳解

 更新時間:2022年09月02日 10:01:40   作者:喬克  
這篇文章主要為大家介紹了Go中的應用配置管理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

問題

  • Go語言在編譯時不會將配置文件這類第三方文件打包進二進制文件中
  • 它既受當前路徑的影響,也會因所填寫的不同而改變,并非是絕對可靠的

解決

命令行參數

在Go語言中,可以直接通過flag標準庫來實現該功能。實現邏輯為,如果存在命令行參數,則優(yōu)先使用命令行參數,否則使用配置文件中的配置參數。

如下:

var (
	port    string
	runMode string
	config  string
)
func init() {	
	// 獲取命令行參數
	err = setupFlag()
	if err != nil {
		log.Fatalf("init.setupFlag err: %v", err)
	}
    ......
}
// 獲取命令行參數
func setupFlag() error {
	flag.StringVar(&port, "port", "", "啟動端口")
	flag.StringVar(&runMode, "mode", "", "啟動模式")
	flag.StringVar(&config, "config", "config/", "指定要使用的配置文件路徑")
	flag.Parse()
	return nil
}

通過上述代碼,我們可以通過標準庫flag讀取命令行參數,然后根據其默認值判斷配置文件是否存在。若存在,則對讀取配置的路徑進行變更,代碼如下:

package setting
import "github.com/spf13/viper"
type Setting struct {
	vp *viper.Viper
}
// 初始化配置文件的基礎屬性
func NewSetting(configs ...string) (*Setting, error) {
	vp := viper.New()
	vp.SetConfigName("config")
	if len(configs) != 0 {
		for _, config := range configs {
			if config != "" {
				vp.AddConfigPath(config)
			}
		}
	} else {
		vp.AddConfigPath("configs/")
	}
	vp.SetConfigType("yaml")
	err := vp.ReadInConfig()
	if err != nil {
		return nil, err
	}
	return &Setting{vp}, nil
}

接下來,對ServerSetting配置項進行覆寫。如果存在,則覆蓋原有的文件配置,使其優(yōu)先級更高,代碼如下:

// 初始化配置文件
func setupSetting() error {
	setting, err := setting2.NewSetting(strings.Split(config, ",")...)
	if err != nil {
		return err
	}
	......
	if port != "" {
		global.ServerSetting.HttpPort = port
	}
	if runMode != "" {
		global.ServerSetting.RunMode = runMode
	}
	return nil
}

然后在運行的時候傳入參數即可:

go run main.go -port=8081 -mode=debug -config=configs/

系統環(huán)境變量

可以將配置文件存放在系統自帶的全局變量中,如$HOME/conf或/etc/conf中,這樣做的好處是不需要重新自定義一個新的系統環(huán)境變量。

一般來說,我們會在程序中內置一些系統環(huán)境變量的讀取,其優(yōu)先級低于命令行參數,但高于文件配置。

打包進二進制文件

可以將配置文件這種第三方文件打包進二進制文件中,這樣就不需要過度關注這些第三方文件了。但這樣做是有一定代價的,因此要注意使用的應用場景,即并非所有的項目都能這樣操作。

首先安裝go-bindata庫,安裝命令如下:

go get -u github.com/go-bindata/go-bindata/...

通過go-bindata庫可以將數據文件轉換為Go代碼。例如,常見的配置文件、資源文件(如Swagger UI)等都可以打包進Go代碼中,這樣就可以“擺脫”靜態(tài)資源文件了。接下來在項目根目錄下執(zhí)行生成命令:

go-bindata -o configs/config.go -pkg-configs configs/config.yaml

執(zhí)行這條命令后,會將 configs/config.yaml 文件打包,并通過-o 選項指定的路徑輸出到configs/config.go文件中,再通過設置的-pkg選項指定生成的packagename為configs,接下來只需執(zhí)行下述代碼,就可以讀取對應的文件內容了:

b,_:=configs.Asset("configs/config.yaml")

把第三方文件打包進二進制文件后,二進制文件必然增大,而且在常規(guī)方法下無法做文件的熱更新和監(jiān)聽,必須要重啟并且重新打包才能使用最新的內容,因此這種方式是有利有弊的。

配置熱更新

開源的fsnotify

既然要做配置熱更新,那么首先要知道配置是什么時候修改的,做了哪些事?因此我們需要對所配置的文件進行監(jiān)聽,只有監(jiān)聽到了,才能知道它做了哪些變更。

開源庫 fsnotify 是用Go語言編寫的跨平臺文件系統監(jiān)聽事件庫,常用于文件監(jiān)聽,因此我們可以借助該庫來實現這個功能。

(1)安裝

go get -u golang.org/x/sys/...
go get -u github.com/fsnotify/fsnotify

fsnotify是基于golang.org/x/sys實現的,并非syscall標準庫,因此在安裝的同時需要更新其版本,確保版本是最新的。

(2)案例

package main
import (
	"gopkg.in/fsnotify.v1"
	"log"
)
func main() {
	watcher, _ := fsnotify.NewWatcher()
	defer watcher.Close()
	done := make(chan bool)
	go func() {
		for {
			select {
			case event, ok := <-watcher.Events:
				if !ok {
					return
				}
				log.Fatal("event: ", event)
				if event.Op&fsnotify.Write == fsnotify.Write {
					log.Println("modified file:", event.Name)
				}
			case err, ok := <-watcher.Errors:
				if !ok {
					return
				}
				log.Fatal("error:", err)
			}
		}
	}()
	path := "configs/config.yaml"
	_ = watcher.Add(path)
	<-done
}

通過監(jiān)聽,我們可以很便捷地知道文件做了哪些變更。進一步來說,我們可以通過對其進行二次封裝,在它的上層實現一些變更動作來完成配置文件的熱更新。

使用viper開源庫實現熱更新

viper開源庫能夠很便捷地實現對文件的監(jiān)聽和熱更新。

打開pkg/setting/section.go文件,針對重載應用配置項,新增如下處理方法:

var sections = make(map[string]interface{})
// 解析配置文件
func (s *Setting) ReadSection(k string, v interface{}) error {
	err := s.vp.UnmarshalKey(k, v)
	if err != nil {
		return err
	}
	if _,ok:=sections[k];!ok{
		sections[k] = v
	}
	return nil
}

首先修改ReadSection方法,增加讀取section的存儲記錄,以便在重新加載配置的方法中進行二次處理。接下來新增ReloadAllSection方法,重新讀取配置,代碼如下:

// 讀取所有配置
func (s *Setting) ReadAllSections() error {
	for k, v := range sections {
		err := s.ReadSection(k, v)
		if err != nil {
			return err
		}
	}
	return nil
}
// 監(jiān)聽配置變化
func (s *Setting) WatchSettingChange()  {
	go func() {
		s.vp.WatchConfig()
		s.vp.OnConfigChange(func(in fsnotify.Event) {
			_ = s.ReloadAllSections()
		})
	}()
}

最后在pkg/setting/setting.go文件中新增文件熱更新的監(jiān)聽和變更處理,代碼如下:

// 初始化配置文件的基礎屬性
func NewSetting(configs ...string) (*Setting, error) {
	vp := viper.New()
	vp.SetConfigName("config")
	for _, config := range configs {
		if config != "" {
			vp.AddConfigPath(config)
		}
	}
	vp.SetConfigType("yaml")
	err := vp.ReadInConfig()
	if err != nil {
		return nil, err
	}
    // 加入熱更新
	s := &Setting{vp: vp}
	s.WatchSettingChange()
	return s, nil
}

在上述代碼中,首先在NewSetting方法中起一個協程,再在里面通過WatchConfig方法對文件配置進行監(jiān)聽,并在OnConfigChange方法中調用剛剛編寫的重載方法ReloadAllSection來處理熱更新的文件監(jiān)聽事件回調,這樣就可以“悄無聲息”地實現一個文件配置熱更新了。

OnConfigChange方法的回調方法形參,其實就是fsnotify。

以上就是Go中的應用配置管理詳解的詳細內容,更多關于Go應用配置管理的資料請關注腳本之家其它相關文章!

相關文章

  • Go語言實現二分查找方法示例

    Go語言實現二分查找方法示例

    這篇文章主要為大家介紹了Go語言實現二分查找方法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • golang 自旋鎖的實現

    golang 自旋鎖的實現

    這篇文章主要介紹了golang 自旋鎖的實現,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11
  • Golang error使用場景介紹

    Golang error使用場景介紹

    我們在使用Golang時,不可避免會遇到異常情況的處理,與Java、Python等語言不同的是,Go中并沒有try...catch...這樣的語句塊,這個時候我們如何才能更好的處理異常呢?本文來教你正確方法
    2023-03-03
  • Go語言使用對稱加密的示例詳解

    Go語言使用對稱加密的示例詳解

    在項目開發(fā)中,我們經常會遇到需要使用對稱密鑰加密的場景,比如客戶端調用接口時,參數包含手機號、身份證號或銀行卡號等。本文將詳細講解Go語言使用對稱加密的方法,需要的可以參考一下
    2022-06-06
  • Go的固定時長定時器和周期性時長定時器

    Go的固定時長定時器和周期性時長定時器

    本文主要介紹了Go的固定時長定時器和周期性時長定時器,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • glow工具在命令行讀取Markdown好物分享

    glow工具在命令行讀取Markdown好物分享

    這篇文章主要為大家介紹了一款實用的命令行工具glow,這個CLI工具可以在命令行讀取Markdown,這對于碼農來說非常友好,使用起來也非常舒爽
    2022-07-07
  • GO語言中=和:=的區(qū)別說明

    GO語言中=和:=的區(qū)別說明

    這篇文章主要介紹了GO語言中=和:=的區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • 并發(fā)安全本地化存儲go-cache讀寫鎖實現多協程并發(fā)訪問

    并發(fā)安全本地化存儲go-cache讀寫鎖實現多協程并發(fā)訪問

    這篇文章主要介紹了并發(fā)安全本地化存儲go-cache讀寫鎖實現多協程并發(fā)訪問,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-10-10
  • Windows系統中搭建Go語言開發(fā)環(huán)境圖文詳解

    Windows系統中搭建Go語言開發(fā)環(huán)境圖文詳解

    GoLand?是?JetBrains?公司推出的商業(yè)?Go?語言集成開發(fā)環(huán)境(IDE),這篇文章主要介紹了Windows系統中搭建Go語言開發(fā)環(huán)境詳解,需要的朋友可以參考下
    2022-10-10
  • 一步步教你編寫可測試的Go語言代碼

    一步步教你編寫可測試的Go語言代碼

    相信每位編程開發(fā)者們應該都知道,Golang作為一門標榜工程化的語言,提供了非常簡便、實用的編寫單元測試的能力。本文通過Golang源碼包中的用法,來學習在實際項目中如何編寫可測試的Go代碼。有需要的朋友們可以參考借鑒,下面跟著小編一起去學習學習吧。
    2016-11-11

最新評論