配置文件热加载的go语言实现

         通常我们更新应用程序的配置文件,都需要手动重启程序或手动重新加载配置。假设一组服务部署在10台机器上,你需要借助批量运维工具执行重启命令,而且10台同时重启可能还会造成服务短暂不可用。要是更新配置后,服务自动刷新配置多好...今天我们就用go实现配置文件热加载的小功能,以后更新配置再也不用手动重启了...

1.基本思路

         通常应用程序启动的流程:加载配置,然后run()。我们怎么做到热加载呢?我们的思路是这样的:

         【1】在加载配置文件之后,启动一个线程。

        【2】该线程定时监听这个配置文件是否有改动。

        【3】如果配置文件有变动,就重新加载一下。

       【4】重新加载之后通知需要使用这些配置的应用程序(进程或线程),实际上就是刷新内存中配置。

 

2.加载配置

       首先我们要实现加载配置功能。假设配置文件是k=v格式的,如下:

 

           

        那我们得写一个解析配置的包了...让我们一起面向对象:

        filename string 配置文件名称

       data map[string]string  将配置文件中的k/v解析存放到map中

       lastModifyTime int64   记录配置文件上一次更改时间

       rwLock sync.RWMutex   读写锁,处理这样一种竞争情况:更新这个结构体时其他线程正在读取改结构体中的内容,后续用到的时候会讲

      notifyList []Notifyer  存放所有观察者,此处我们用到了观察者模式,也就是需要用到这个配置的对象,我们就把它加到这个切片。当配置更新之后,通知切片中的对象配置更新了。

      接下来我们可以给这个结构体添加一些方法了:

2.1 构造函数

 1 func NewConfig(file string)(conf *Config, err error){
 2    conf = &Config{
 3        filename: file,
 4        data: make(map[string]string, 1024),
 5    }
 6
 7    m, err := conf.parse()
 8    if err != nil {
 9        fmt.Printf("parse conf error:%v\n", err)
10        return
11    }
12
13    // 将解析配置文件后的数据更新到结构体的map中,写锁
14    conf.rwLock.Lock()
15    conf.data = m
16    conf.rwLock.Unlock()
17
18    // 启一个后台线程去检测配置文件是否更改
19    go conf.reload()
20    return
21}

构造函数做了三件事:

   【1】初始化Config 

   【2】调用parse()函数,解析配置文件,并把解析后的map更新到Config 

   【3】启动一个线程,准确说是启动一个goroutine,即reload() 

   注意此处更新map时加了写锁了,目的在于不影响拥有读锁的线程读取数据。

2.2 parse()

     解析函数比较简单,主要是读取配置文件,一行行解析,数据存放在map中。

 1 func (c *Config) parse() (m map[string]string, err error) {
 2    // 如果在parse()中定义一个map,这样就是一个新的map不用加锁
 3    m = make(map[string]string, 1024)
 4
 5    f, err := os.Open(c.filename)
 6    if err != nil {
 7    
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值