conf: 监听配置文件更新

可以通过保存/touch 配置文件更新配置
pull/1/head
miraclesu 2017-03-03 15:13:42 +08:00
parent 84eb20aef5
commit aedb0f6d10
3 changed files with 86 additions and 13 deletions

View File

@ -47,7 +47,7 @@ func main() {
log.Noticef("cronsun %s service started, Ctrl+C or send kill sign to exit", n.String()) log.Noticef("cronsun %s service started, Ctrl+C or send kill sign to exit", n.String())
// 注册退出事件 // 注册退出事件
event.On(event.EXIT, n.Stop) event.On(event.EXIT, n.Stop, conf.Exit)
// 监听退出信号 // 监听退出信号
event.Wait() event.Wait()
// 处理退出事件 // 处理退出事件

View File

@ -44,7 +44,7 @@ func main() {
log.Noticef("cronsun web server started on %s, Ctrl+C or send kill sign to exit", conf.Config.Web.BindAddr) log.Noticef("cronsun web server started on %s, Ctrl+C or send kill sign to exit", conf.Config.Web.BindAddr)
// 注册退出事件 // 注册退出事件
// event.On(event.EXIT, n.Stop) event.On(event.EXIT, conf.Exit)
// 监听退出信号 // 监听退出信号
event.Wait() event.Wait()
event.Emit(event.EXIT, nil) event.Emit(event.EXIT, nil)

View File

@ -6,6 +6,7 @@ import (
"time" "time"
client "github.com/coreos/etcd/clientv3" client "github.com/coreos/etcd/clientv3"
"github.com/fsnotify/fsnotify"
"sunteng/commons/confutil" "sunteng/commons/confutil"
"sunteng/commons/db/imgo" "sunteng/commons/db/imgo"
@ -18,6 +19,9 @@ var (
Config = new(Conf) Config = new(Conf)
initialized bool initialized bool
watcher *fsnotify.Watcher
exitChan = make(chan struct{})
) )
func Init() error { func Init() error {
@ -26,20 +30,12 @@ func Init() error {
} }
flag.Parse() flag.Parse()
err := confutil.LoadExtendConf(*confFile, Config) if err := Config.parse(); err != nil {
if err != nil {
return err return err
} }
if err := Config.watch(); err != nil {
if Config.Etcd.DialTimeout > 0 { return err
Config.Etcd.DialTimeout *= time.Second
} }
log.InitConf(Config.Log)
Config.Cmd = cleanKeyPrefix(Config.Cmd)
Config.Proc = cleanKeyPrefix(Config.Proc)
Config.Group = cleanKeyPrefix(Config.Group)
initialized = true initialized = true
return nil return nil
} }
@ -89,3 +85,80 @@ func cleanKeyPrefix(p string) string {
return p return p
} }
func (c *Conf) parse() error {
err := confutil.LoadExtendConf(*confFile, c)
if err != nil {
return err
}
if c.Etcd.DialTimeout > 0 {
c.Etcd.DialTimeout *= time.Second
}
log.InitConf(c.Log)
c.Cmd = cleanKeyPrefix(c.Cmd)
c.Proc = cleanKeyPrefix(c.Proc)
c.Group = cleanKeyPrefix(c.Group)
return nil
}
func (c *Conf) watch() error {
var err error
watcher, err = fsnotify.NewWatcher()
if err != nil {
return err
}
go func() {
duration := 3 * time.Second
timer, update := time.NewTimer(duration), false
for {
select {
case <-exitChan:
return
case event := <-watcher.Events:
// 保存文件时会产生多个事件
if event.Op&(fsnotify.Write|fsnotify.Chmod) > 0 {
timer.Reset(duration)
update = true
}
case <-timer.C:
if update {
c.reload()
update = false
}
timer.Reset(duration)
case err := <-watcher.Errors:
log.Warnf("config watcher err: %v", err)
}
}
}()
return watcher.Add(*confFile)
}
// 重新加载配置项
// 注:与系统资源相关的选项不生效,需重启程序
// Etcd
// Mgo
// Web
func (c *Conf) reload() {
cf := new(Conf)
if err := cf.parse(); err != nil {
log.Warn("config file reload err:", err.Error())
return
}
*c = *cf
log.Noticef("config file[%s] reload success", *confFile)
return
}
func Exit(i interface{}) {
close(exitChan)
if watcher != nil {
watcher.Close()
}
}