核心对象
TemplateResource is the representation of a parsed template resource.
type TemplateResource struct {
CheckCmd string `toml:"check_cmd"`
Dest string
FileMode os.FileMode
Gid int
Keys []string
Mode string
Prefix string
ReloadCmd string `toml:"reload_cmd"`
Src string
StageFile *os.File
Uid int
funcMap map[string]interface{}
lastIndex uint64
keepStageFile bool
noop bool
store memkv.Store
storeClient backends.StoreClient
syncOnly bool
PGPPrivateKey []byte
}
配置更新
process is a convenience function that wraps calls to the three main tasks required to keep local configuration files in sync. First we gather vars from the store, then we stage a candidate configuration file, and finally sync things up. It returns an error if any.
func (t *TemplateResource) process() error {
if err := t.setFileMode(); err != nil {
return err
}
if err := t.setVars(); err != nil {
return err
}
if err := t.createStageFile(); err != nil {
return err
}
if err := t.sync(); err != nil {
return err
}
return nil
}
- 从存储中获取变量
- 暂存配置文件
- 同步
定时刷新的实现
type intervalProcessor struct {
config Config
stopChan chan bool
doneChan chan bool
errChan chan error
interval int
}
订阅刷新的实现
type watchProcessor struct {
config Config
stopChan chan bool
doneChan chan bool
errChan chan error
wg sync.WaitGroup
}
订阅的实现
store cline 提供两个方法
// The StoreClient interface is implemented by objects that can retrieve
// key/value pairs from a backend store.
type StoreClient interface {
GetValues(keys []string) (map[string]string, error)
WatchPrefix(prefix string, keys []string, waitIndex uint64, stopChan chan bool) (uint64, error)
}
主要看一下consul的实现
func (c *ConsulClient) WatchPrefix(prefix string, keys []string, waitIndex uint64, stopChan chan bool) (uint64, error) {
respChan := make(chan watchResponse)
go func() {
opts := api.QueryOptions{
WaitIndex: waitIndex,
}
_, meta, err := c.client.List(prefix, &opts)
if err != nil {
respChan <- watchResponse{waitIndex, err}
return
}
respChan <- watchResponse{meta.LastIndex, err}
}()
select {
case <-stopChan:
return waitIndex, nil
case r := <-respChan:
return r.waitIndex, r.err
}
}
总结
根据命名简要的看完了confd的配置更新的代码。confd支持两种模式的Processor,1. 定时更新(缺省);2. 订阅更新。定时更新特别简单,周期从k/v存储中拉去变量,然后新建临时的配置文件,最后用新建的临时配置文件替换目标位置的配置。定时更新的主要区别是,通过创建channel去订阅(阻塞查询)k/v存储中关系的index有误发生变化。