亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Golang > 正文

使用Go語言實現配置文件熱加載功能

2020-04-01 18:58:20
字體:
來源:轉載
供稿:網友

 說到配置文件熱加載,這個功能在很多框架中都提供了,如beego,實現的效果就是當你修改文件后,會把你修改后的配置重新加載到配置文件中,而不用重啟程序,這個功能在日常中還是非常實用的,畢竟很多時候,線上的配置文件不是想改就能改的。

這次就自己實現一個配置文件的熱加載功能的包,并通過一個簡單的例子對完成的包進行使用驗證

配置文件熱加載包的是實現

其實整體的思路還是比較簡單的,當獲取配置文件內容后,會開啟一個goroutine,去 循環讀配置文件,當然這里不可能不限制的一直循環,而是設置了一個定時器,定時去讀文件,根據文件的修改時間是否變化,從而確定是否重新reload配置文件

實現的config 包的文件結構為:

├── config.go└── config_notify.go

config.go:代碼的主要處理邏輯
config_notify.go:主要定義了一個接口,用于當文件修改時間變化的時候執行回調

config_notify.go的代碼相對來說比較簡單,我們先看看這個代碼:

package config// 定義一個通知的接口type Notifyer interface { Callback(*Config)}

這樣當我們實現了Callback這個方法的時候,我們就實現了Notifyer這個接口,具體的調用在后面會說

在config.go中我們頂一個了一個結構體:

type Config struct { filename string lastModifyTime int64 data map[string]string rwLock sync.RWMutex notifyList []Notifyer}

結構體中主要包含幾個字段:

filename:配置文件名字
lastModifyTime:配置文件的最后修改時間
data:用于將從配置文件中讀取的內容存儲為map
rwlock:讀寫鎖
notifyList:用于將調用該包的程序追加到切片中,用于通知調用上面在config_notify.go定義的callback回調函數

關于讀取配置文件中的內容并存儲到map中,這里定義了一個方法實現:

func (c *Config) parse()(m map[string]string,err error){ // 讀文件并或將文件中的數據以k/v的形式存儲到map中 m = make(map[string]string,1024) file,err := os.Open(c.filename) if err != nil{  return } var lineNo int reader := bufio.NewReader(file) for{  // 一行行的讀文件  line,errRet := reader.ReadString('/n')  if errRet == io.EOF{   // 表示讀到文件的末尾   break  }  if errRet != nil{   // 表示讀文件出問題   err = errRet   return  }  lineNo++  line = strings.TrimSpace(line) // 取出空格  if len(line) == 0 || line[0] == '/n' || line[0] == '+' || line[0] == ';'{   // 當前行為空行或者是注釋行等   continue  }  arr := strings.Split(line,"=") // 通過=進行切割取出k/v結構  if len(arr) == 0{   fmt.Printf("invalid config,line:%d/n",lineNo)   continue  }  key := strings.TrimSpace(arr[0])  if len(key) == 0{   fmt.Printf("invalid config,line:%d/n",lineNo)   continue  }  if len(arr) == 1{   m[key] = ""   continue  }  value := strings.TrimSpace(arr[1])  m[key] = value } return}

而最后我們就需要一個定時器,每隔一段時間判斷配置文件的最后修改時間是否變化,如果變化則重新讀取一次文件并將文件內容存儲到map中。

func (c *Config) reload(){ // 這里啟動一個定時器,每5秒重新加載一次配置文件 ticker := time.NewTicker(time.Second*5) for _ = range ticker.C{  func(){   file,err := os.Open(c.filename)   if err != nil{    fmt.Printf("open %s failed,err:%v/n",c.filename,err)    return   }   defer file.Close()   fileInfo,err := file.Stat()   if err != nil{    fmt.Printf("stat %s failed,err:%v/n",c.filename,err)    return   }   curModifyTime := fileInfo.ModTime().Unix()   fmt.Printf("%v --- %v/n",curModifyTime,c.lastModifyTime)   //判斷文件的修改時間是否大于最后一次修改時間   if curModifyTime > c.lastModifyTime{    m,err := c.parse()    if err != nil{     fmt.Println("parse failed,err:",err)     return    }    c.rwLock.Lock()    c.data = m    c.rwLock.Unlock()    for _, n:=range c.notifyList{     n.Callback(c)    }    c.lastModifyTime = curModifyTime   }  }() }

關于config完整的代碼地址:https://github.com/pythonsite/go_simple_code/tree/master/config

一個演示上述包的例子

這里一個簡單的例子,代碼的邏輯也非常簡單就是寫一個循環從配置文件讀取配置信息,當然這里是為了測試效果,寫成了循環。這里有個問題需要注意,就是在配置文件中存放數據的時候應該是如下格式存儲

listen_addr = localhostserver_port = 1000# Nginx addrnginx_addr = 192.168.1.2:9090

測試代碼的主要結構如下:

├── config.conf
└── main.go

config.conf為配置文件
main.go 為主要測試代碼

type AppConfig struct { port int nginxAddr string}type AppconfigMgr struct { config atomic.Value}var appConfigMgr = &AppconfigMgr{}func(a *AppconfigMgr)Callback(conf *config.Config){ var appConfig = &AppConfig{} port,err := conf.GetInt("server_port") if err != nil{  fmt.Println("get port failed,err:",err)  return } appConfig.port = port fmt.Println("port:",appConfig.port) nginxAddr,err := conf.GetString("nginx_addr") if err != nil{  fmt.Println("get nginx addr failed,err:",err)  return } appConfig.nginxAddr = nginxAddr fmt.Println("nginx addr :",appConfig.nginxAddr) appConfigMgr.config.Store(appConfig)}func run(){ for {  // 每5秒打印一次數據,查看自己更改配置文件后是否可以熱刷新  appConfig := appConfigMgr.config.Load().(*AppConfig)  fmt.Println("port:",appConfig.port)  fmt.Println("nginx addr:",appConfig.nginxAddr)  time.Sleep(5* time.Second) }}func main() { conf,err := config.NewConfig("/Users/zhaofan/go_project/src/go_dev/13/config_test/config.conf") if err != nil{  fmt.Println("parse config failed,err:",err)  return } //打開文件獲取內容后,將自己加入到被通知的切片中 conf.AddNotifyer(appConfigMgr) var appConfig = &AppConfig{} appConfig.port,err = conf.GetInt("server_port") if err != nil{  fmt.Println("get port failed,err:",err)  return } fmt.Println("port:",appConfig.port) appConfig.nginxAddr,err = conf.GetString("nginx_addr") if err != nil{  fmt.Println("get nginx addr failed,err:",err)  return } fmt.Println("nginx addr:",appConfig.nginxAddr) appConfigMgr.config.Store(appConfig) run()}

上面代碼中有一段代碼非常重要:

func(a *AppconfigMgr)Callback(conf *config.Config){ var appConfig = &AppConfig{} port,err := conf.GetInt("server_port") if err != nil{  fmt.Println("get port failed,err:",err)  return } appConfig.port = port fmt.Println("port:",appConfig.port) nginxAddr,err := conf.GetString("nginx_addr") if err != nil{  fmt.Println("get nginx addr failed,err:",err)  return } appConfig.nginxAddr = nginxAddr fmt.Println("nginx addr :",appConfig.nginxAddr) appConfigMgr.config.Store(appConfig)}

這里我們實現了Callback方法,同時就實現了我們在config包中定義的那個接口

測試效果如下,當我們更改配置文件后,程序中的配置文件也被重新加載

go語言,配置文件,熱加載

完整的測試代碼地址:https://github.com/pythonsite/go_simple_code/tree/master/config_test

總結

以上所述是小編給大家介紹的使用Go語言實現配置文件熱加載功能,希望對大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會及時回復大家的!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品观看在线亚洲人成网| 欧美xxxwww| 成人免费午夜电影| 日本韩国在线不卡| 国产精品爽爽ⅴa在线观看| 92国产精品视频| 国产精品久久久久99| 亚洲第一福利在线观看| 亚洲男人的天堂在线播放| 国产一区深夜福利| 国产亚洲一区二区在线| 久久99久久亚洲国产| 国产精品丝袜视频| 欧美成人午夜视频| 91av在线国产| 原创国产精品91| 亚洲精品美女久久久| 成人亲热视频网站| 精品二区三区线观看| 国产不卡精品视男人的天堂| 国产成人精品在线播放| 亚洲欧美日韩国产中文专区| 色诱女教师一区二区三区| 国产精品久久久久久影视| 欧美成aaa人片免费看| 亚洲视频999| 亚洲成人国产精品| 国产成人精彩在线视频九色| 亚洲人av在线影院| 国产aⅴ夜夜欢一区二区三区| 精品女厕一区二区三区| 国产欧美最新羞羞视频在线观看| 欧美一级淫片丝袜脚交| 亚洲自拍在线观看| 一区二区三区无码高清视频| 国产99久久精品一区二区 夜夜躁日日躁| 亚洲国产精品专区久久| 日韩经典中文字幕在线观看| 精品香蕉一区二区三区| 午夜精品国产精品大乳美女| 成人日韩av在线| 欧美中文字幕在线| 亚洲最新中文字幕| 欧美日韩国产精品一区二区三区四区| 欧美大奶子在线| 91美女福利视频高清| 中文字幕亚洲无线码在线一区| 日韩免费观看视频| 欧美性69xxxx肥| 欧美高清一级大片| 日韩大片在线观看视频| 国产欧美精品一区二区三区-老狼| 91在线观看免费高清完整版在线观看| 国内精品国产三级国产在线专| 欧美人与物videos| 中文一区二区视频| 亚洲欧美国产va在线影院| 午夜欧美不卡精品aaaaa| 55夜色66夜色国产精品视频| 精品国产一区二区三区久久狼5月| 国产精品免费一区二区三区都可以| 久久69精品久久久久久久电影好| 中文字幕精品一区久久久久| 亚洲奶大毛多的老太婆| 欧美日韩亚洲网| 国产一区二区三区网站| 8050国产精品久久久久久| 欧美日韩国产精品专区| 日本欧美精品在线| 久久6精品影院| 日本久久亚洲电影| 精品久久久999| 久久久久久久久久久亚洲| 日韩一二三在线视频播| 欧洲中文字幕国产精品| 亚洲福利视频网| 亚洲欧洲日产国产网站| 国产91热爆ts人妖在线| 欧美日韩人人澡狠狠躁视频| 成人网在线免费观看| 色偷偷av一区二区三区| 91日韩在线播放| 亚洲另类欧美自拍| 国产婷婷97碰碰久久人人蜜臀| 国产精品白嫩初高中害羞小美女| 久久人人爽国产| 国产精品视频久久久久| 精品综合久久久久久97| 欧美成aaa人片在线观看蜜臀| 国产精品入口免费视频一| 伊人伊人伊人久久| 日韩中文字幕精品视频| 97国产精品视频人人做人人爱| 成人精品久久久| 性欧美在线看片a免费观看| 亚洲深夜福利网站| 久久久久久久网站| 欧美黑人狂野猛交老妇| 国产一区二区三区精品久久久| 九色精品免费永久在线| 亚洲第一区第二区| 精品久久久久久国产91| 在线不卡国产精品| 欧美激情视频三区| 亚洲自拍在线观看| 亚洲欧美国产一本综合首页| 日韩在线观看精品| 精品在线小视频| 亚洲色图日韩av| 亚洲精品suv精品一区二区| 欧美成人黑人xx视频免费观看| 91免费人成网站在线观看18| 日韩福利视频在线观看| 欧美性猛交xxxx乱大交极品| 日韩国产在线看| 欧美www视频在线观看| 日韩有码视频在线| xxx一区二区| 亚洲欧美另类中文字幕| yw.139尤物在线精品视频| 一区二区三区无码高清视频| 日韩国产欧美精品一区二区三区| 欧美激情中文网| 在线观看不卡av| 国产亚洲欧洲高清| 在线观看亚洲区| 日本欧美黄网站| 亚洲美女av网站| 欧美日韩国产丝袜另类| 日韩精品欧美国产精品忘忧草| 色偷偷噜噜噜亚洲男人| 欧美国产日韩精品| 亚洲精品电影网在线观看| 久久69精品久久久久久久电影好| 最近中文字幕2019免费| 1769国产精品| 欧洲成人性视频| 日韩av在线影视| 成人福利在线观看| 久久亚洲精品一区二区| 国产91对白在线播放| 亚洲国产成人精品电影| 亚洲成人av在线| 色综久久综合桃花网| 欧美性xxxxx极品娇小| 亚洲国产日韩欧美在线动漫| 中文字幕亚洲综合久久筱田步美| 成人免费在线视频网址| 国产精品久久久久久久久久小说| 亚洲欧美视频在线| 91亚洲国产成人精品性色| 国产精品一香蕉国产线看观看| 91高清免费在线观看| 欧洲成人午夜免费大片| 日韩视频在线免费| 欧美一区二区三区……| 午夜精品在线视频| 国产日韩精品综合网站| 久久久999精品免费| 91精品啪在线观看麻豆免费| 国产精品免费久久久| 欧美日韩国产精品一区二区三区四区| 国产热re99久久6国产精品| www高清在线视频日韩欧美|