好湿?好紧?好多水好爽自慰,久久久噜久噜久久综合,成人做爰A片免费看黄冈,机机对机机30分钟无遮挡

主頁 > 知識庫 > 使用Go語言實現配置文件熱加載功能

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

熱門標簽:阿里云ai電話機器人 釘釘有地圖標注功能嗎 濱州自動電銷機器人排名 惠州電銷防封電話卡 浙江高頻外呼系統多少錢一個月 汕頭小型外呼系統 建造者2地圖標注 鄭州亮點科技用的什么外呼系統 黃岡人工智能電銷機器人哪個好

 說到配置文件熱加載,這個功能在很多框架中都提供了,如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 = localhost
server_port = 1000
# Nginx addr
nginx_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包中定義的那個接口

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

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

總結

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

您可能感興趣的文章:
  • MongoDB 3.4配置文件避免入坑的注意事項
  • MongoDB的安裝及配置文件選項全解
  • 在Django中同時使用多個配置文件的方法
  • python用ConfigObj讀寫配置文件的實現代碼

標簽:泰安 阿壩 昭通 駐馬店 東營 滄州 瀘州 晉中

巨人網絡通訊聲明:本文標題《使用Go語言實現配置文件熱加載功能》,本文關鍵詞  使用,語言,實現,配置文件,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《使用Go語言實現配置文件熱加載功能》相關的同類信息!
  • 本頁收集關于使用Go語言實現配置文件熱加載功能的相關信息資訊供網民參考!
  • 推薦文章
    主站蜘蛛池模板: 牡丹国际期货下载app| 偷窥孕妇浴室洗澡更衣视频| 国产黄A三级三级三级看三级男男| 蜜桃AV精品一区二区三区在线观看| 玖玖成人网| chillchill短视频| 大胸美女脱个精光图片| 强制榨精小说合集| 在线无码精品秘?入口免费77 | 新野县| 日韩三?理伦片在线| 国精产品一区一区三区四区| 秋霞一级毛片搂丝片| 色婷婷在线视频观看| 亚洲性夜夜综合久久麻豆| 电梯里被猛烈的进出嗯啊视频免费| 性久久久久久久久久| 梯子加速器| 公公舔我逼| 少妇天堂色噜噜7777 | 男生操女生的| 黑人黄色片| 女人快活的呻吟着迎合着| 边脱边吻边摸下面视频| 国产一极毛片| 福利一区国产| 国模小树粉嫩私外m133| 寡妇老熟女XXX| 免费羞羞视频网站| 好大好爽快点深一点播放| 亚洲欧美另类视频| 亚洲日韩啪啪无码AAAAA | 日本免费黄色电影| 女性同房干涩没水怎么办| 韩国做爰A片免费看吸乳| 日本japanese丰满高清成人视| runaway在线观看免费韩国动漫| 小荡货自己动h| 国产精品无码亚洲欧美仙踪林| 小草青青爱久久AV片| 久久视热这只是精品222|