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

Go語言實(shí)現(xiàn)配置熱加載的方法分享

 更新時(shí)間:2023年05月24日 11:41:22   作者:tracy小貓  
web項(xiàng)目,經(jīng)常需要熱啟動(dòng)各種各樣的配置信息,一旦這些服務(wù)發(fā)生變更,我們需要重新啟動(dòng)web server,以使配置生效,實(shí)現(xiàn)配置熱加載,本文為大家整理了幾個(gè)方法實(shí)現(xiàn)這個(gè)需求,需要的可以參考下

概述

web項(xiàng)目,經(jīng)常需要熱啟動(dòng)各種各樣的配置信息,一旦這些服務(wù)發(fā)生變更,我們需要重新啟動(dòng)web server,以使配置生效,實(shí)現(xiàn)配置熱加載。這里有幾種方法實(shí)現(xiàn)這個(gè)需求。

go 定時(shí)器協(xié)程實(shí)現(xiàn)

項(xiàng)目結(jié)構(gòu)

首先來看一下整個(gè)項(xiàng)目的目錄結(jié)構(gòu):

- dyconfig // 項(xiàng)目地址
  - config   // 配置文件目錄
      - api.yaml  // 采用yaml格式文件
  - global // 代碼文件夾
      - config
              - config_define
              - init
              - reload
  - go.mod // go package管理依賴的包文件
  - go.sum // go package管理打包產(chǎn)生的文件
  - main.go // web server的入口,主函數(shù)

代碼細(xì)節(jié)

接下來依次看一下各文件的主體內(nèi)容:

conf/api.yaml文件定義了配置項(xiàng),包含server的host及port信息。

service:
    server:
          env: dev
          host: 127.0.0.1
          port: 9902

global/init.go

package global
import (
 "context"
 "path"
)
type Config struct {
 Conf struct {
    FilePath       string
    LastModifyTime int64
 }
 ctx    context.Context
 cancel context.CancelFunc
}
func NewConfig() (*Config, error) {
 conf := new(Config)
 conf.ctx, conf.cancel = context.WithCancel(context.Background())
 conf.Conf.FilePath = path.Join("./config", "api.yaml")
 APIconfig = conf.loadRoute()
 go conf.reload() //開啟協(xié)程監(jiān)聽routeNotify
 go func() {
    for {
       select {
       case lastModifyTime, ok := <-routeNotify:
          if !ok {
             return
          }
          conf.Conf.LastModifyTime = lastModifyTime
          route := routeAtomic.Load().(*APIConf)
          if route != nil {
             APIconfig = route
          }
       }
    }
 }()
 return conf, nil
}
func (c *Config) Stop() {
 c.cancel()
}

定義Config 根據(jù)LastModifyTime 判斷是否有發(fā)生變化,F(xiàn)ilePath為文件路徑

go conf.reload()

開啟協(xié)程監(jiān)聽routeNotify,routeNotify內(nèi)容是文件修改時(shí)間的timestamp

global/reload.go

package global
import (
   "fmt"
   "gopkg.in/yaml.v3"
   "io/ioutil"
   "os"
   "sync/atomic"
   "time"
)
const (
   CheckInterval = 5 * time.Second
)
var (
   routeAtomic atomic.Value //原子性,解決并發(fā)問題
   routeNotify = make(chan int64) //channel 放入timestamp
)
func (c *Config) reload() {
   ticker := time.NewTicker(CheckInterval)
   defer ticker.Stop()
   for {
      select {
      case <-c.ctx.Done():
         close(routeNotify)
         return
      case <-ticker.C:
         if f, err := os.Stat(c.Route.FilePath); err != nil {
            fmt.Println(err)
         } else if f.ModTime().Unix() != c.Route.LastModifyTime {
            if c.Route.LastModifyTime == 0 {
               c.Route.LastModifyTime = f.ModTime().Unix()
            } else {
               routeAtomic.Store(c.loadConfig())
               routeNotify <- f.ModTime().Unix()
               fmt.Println("配置文件發(fā)生變化")
            }
         }
      }
   }
}
func (c *Config) loadConfig() *APIConf {
   if fp, err := ioutil.ReadFile(c.Route.FilePath); err != nil {
      fmt.Println(err)
      return nil
   } else {
      route := new(APIConf)
      if err := yaml.Unmarshal(fp, &route); err != nil {
         return nil
      }
      return route
   }
}

定時(shí)器監(jiān)聽文件的修改時(shí)間與LastModifyTime是否相同,如果不同,則

package global
var (
   APIconfig = new(APIConf)
)
package global
type ServiceConf struct {
   Server struct {
      Env  string `yaml:"env"` 
      Host string `yaml:"host"`
      Port string  `yaml:"port"`
   } `yaml:"server"`
}
type APIConf struct { 
   Service ServiceConf `yaml:"service"`
}

mian

package main
import (
   "dyconfig/global"
   "fmt"
   "github.com/gin-gonic/gin"
)
func main() {
   if conf, err := global.NewConfig(); err != nil { // 初始化配置
      fmt.Println(err)
   } else {
      defer conf.Stop()
   }
   gin.SetMode(gin.DebugMode)
   r := gin.Default()
   r.GET("/ping", func(context *gin.Context) {
      fmt.Println("當(dāng)前host是: ", global.APIconfig.Service.Server.Host)
      fmt.Println("當(dāng)前port是: ", global.APIconfig.Service.Server.Port)
      context.JSON(
         200, gin.H{
            "host": global.APIconfig.Service.Server.Host,
            "port": &global.APIconfig.Service.Server.Port,
         })
   })
   port := global.APIconfig.Service.Server.Port
   fmt.Println("當(dāng)前host是: ", global.APIconfig.Service.Server.Host)
   fmt.Println("當(dāng)前port是: ", global.APIconfig.Service.Server.Port)
   port = ":" + port
   _ = r.Run(port)
}

調(diào)用示例

1.第一次調(diào)用,port為9902

2. 修改config ,port為9903

到此這篇關(guān)于Go語言實(shí)現(xiàn)配置熱加載的方法分享的文章就介紹到這了,更多相關(guān)Go語言配置熱加載內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 正則表達(dá)式詳解以及Golang中的應(yīng)用示例

    正則表達(dá)式詳解以及Golang中的應(yīng)用示例

    這篇文章主要介紹了正則表達(dá)式詳解以及Golang中應(yīng)用的相關(guān)資料,Go語言的regexp包是Go語言標(biāo)準(zhǔn)庫中的一個(gè)重要組件,用于處理正則表達(dá)式,文中通過代碼將用法介紹的非常詳細(xì),需要的朋友可以參考下
    2025-07-07
  • go語言的變量定義示例詳解

    go語言的變量定義示例詳解

    這篇文章主要為大家介紹了go語言的變量定義示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • go語言-在mac下brew升級(jí)golang

    go語言-在mac下brew升級(jí)golang

    這篇文章主要介紹了go語言-在mac下brew升級(jí)golang,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • golang API請(qǐng)求隊(duì)列的實(shí)現(xiàn)

    golang API請(qǐng)求隊(duì)列的實(shí)現(xiàn)

    本文主要介紹了golang API請(qǐng)求隊(duì)列的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • golang結(jié)構(gòu)體指針的實(shí)現(xiàn)

    golang結(jié)構(gòu)體指針的實(shí)現(xiàn)

    這篇文章主要介紹了golang結(jié)構(gòu)體指針的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-06-06
  • grom設(shè)置全局日志實(shí)現(xiàn)執(zhí)行并打印sql語句

    grom設(shè)置全局日志實(shí)現(xiàn)執(zhí)行并打印sql語句

    本文主要介紹了grom設(shè)置全局日志實(shí)現(xiàn)執(zhí)行并打印sql語句,包括設(shè)置日志級(jí)別、實(shí)現(xiàn)自定義Logger接口以及如何使用GORM的默認(rèn)logger,通過這些方法,可以更好地控制和記錄數(shù)據(jù)庫操作的日志信息
    2025-03-03
  • Go返回int64類型字段超出javascript Number范圍的解決方法

    Go返回int64類型字段超出javascript Number范圍的解決方法

    這篇文章主要介紹了Go返回int64類型字段超出javascript Number范圍的解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • GO語言 復(fù)合類型專題

    GO語言 復(fù)合類型專題

    這篇文章主要介紹了GO語言 復(fù)合類型的的相關(guān)資料,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • golang優(yōu)化目錄遍歷的實(shí)現(xiàn)方法

    golang優(yōu)化目錄遍歷的實(shí)現(xiàn)方法

    對(duì)于go1.16的新變化,大家印象最深的可能是io包的大規(guī)模重構(gòu),但這個(gè)重構(gòu)實(shí)際上還引進(jìn)了一個(gè)優(yōu)化,這篇文章要說的就是這個(gè)優(yōu)化,所以本將給大家介紹golang是如何優(yōu)化目錄遍歷的,需要的朋友可以參考下
    2024-08-08
  • Go標(biāo)準(zhǔn)容器之Ring的使用說明

    Go標(biāo)準(zhǔn)容器之Ring的使用說明

    這篇文章主要介紹了Go標(biāo)準(zhǔn)容器之Ring的使用說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05

最新評(píng)論

华池县| 平泉县| 武汉市| 班玛县| 通渭县| 环江| 息烽县| 新乡县| 枣强县| 阳谷县| 东城区| 敦化市| 长丰县| 资源县| 韶山市| 丹巴县| 台湾省| 汾西县| 桦川县| 余江县| 蕉岭县| 阿克苏市| 宁乡县| 扬州市| 唐河县| 十堰市| 铜陵市| 左云县| 紫云| 宣化县| 长宁县| 平阳县| 永春县| 丹东市| 北碚区| 舒城县| 读书| 南昌市| 西昌市| 诸暨市| 长葛市|