micro.newService()中newOptionsweb
func newOptions(opts ...Option) Options { opt := Options{ Auth: auth.DefaultAuth, Broker: broker.DefaultBroker, Cmd: cmd.DefaultCmd, Config: config.DefaultConfig, Client: client.DefaultClient, Server: server.DefaultServer, Store: store.DefaultStore, Registry: registry.DefaultRegistry, Router: router.DefaultRouter, Runtime: runtime.DefaultRuntime, Transport: transport.DefaultTransport, Context: context.Background(), Signal: true, } for _, o := range opts { o(&opt) } return opt }
初始化了一堆基础设置,来看看configconfig.DefaultConfig,
在config/config.go中json
var ( // Default Config Manager DefaultConfig, _ = NewConfig() ) // NewConfig returns new config func NewConfig(opts ...Option) (Config, error) { return newConfig(opts...) } func newConfig(opts ...Option) (Config, error) { var c config c.Init(opts...) go c.run() return &c, nil } func (c *config) Init(opts ...Option) error { c.opts = Options{ Reader: json.NewReader(), } c.exit = make(chan bool) for _, o := range opts { o(&c.opts) } // default loader uses the configured reader if c.opts.Loader == nil { c.opts.Loader = memory.NewLoader(memory.WithReader(c.opts.Reader)) } err := c.opts.Loader.Load(c.opts.Source...) if err != nil { return err } c.snap, err = c.opts.Loader.Snapshot() if err != nil { return err } c.vals, err = c.opts.Reader.Values(c.snap.ChangeSet) if err != nil { return err } return nil } func (c *config) run() { watch := func(w loader.Watcher) error { for { // get changeset snap, err := w.Next() if err != nil { return err } c.Lock() if c.snap.Version >= snap.Version { c.Unlock() continue } // save c.snap = snap // set values c.vals, _ = c.opts.Reader.Values(snap.ChangeSet) c.Unlock() } } for { w, err := c.opts.Loader.Watch() if err != nil { time.Sleep(time.Second) continue } done := make(chan bool) // the stop watch func go func() { select { case <-done: case <-c.exit: } w.Stop() }() // block watch if err := watch(w); err != nil { // do something better time.Sleep(time.Second) } // close done chan close(done) // if the config is closed exit select { case <-c.exit: return default: } } }
看看Init()
左作了什么segmentfault
设置默认loader,c.opts.Loader默认是memory memory.NewLoader()
[config/loader/memory/memory.go]app
设置m.sets,并watch()
每一个options.Source,看看watch()
作了什么函数
定义watch()函数插件
调用watcher.Next(),下面看看next()作了什么code
调用update()router
调用Watch()函数返回watcher,注意W是大写,调用的是memory.Watch()server
调用c.opts.Loader.Load()协程
调用reload()
调用c.opts.Loader.Snapshot()
Sync()
同步配置c.opts.Reader.Values()
,赋值config.vals【reader.Values
类型】绕来绕去,终于完了。
主流程其实并不复杂,主要是涉及到watch更新,因此比较绕。
config这块实际上是比较独立的包,能够在其余项目中引用。
go micro 分析系列文章
go micro server 启动分析
go micro client
go micro broker
go micro cmd
go micro config
go micro store
go micro registry
go micro router
go micro runtime
go micro transport
go micro web
go micro registry 插件consul
go micro plugin
go micro jwt 网关鉴权
go micro 链路追踪
go micro 熔断与限流
go micro wrapper 中间件
go micro metrics 接入Prometheus、Grafana