go kratos源碼及配置解析
更新時間:2022年12月05日 11:57:55 作者:小宇渣渣渣
這篇文章主要為大家介紹了go kratos源碼及配置解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
相關類圖
項目啟動時一般前置條件為解析配置文件, 我們看下這塊是怎么設計的.

流程解釋
- config 實現 config Interface 接口, 初始化reader對象
- 調用Load方法, 通過入口注入的不同文件源, 調用實現了source interface 對應的Load方法(以file舉例子)
- file 通過 Load 入口, 判斷是目錄還是文件, 執(zhí)行對應的方法, 拿到文件內容返回
- config 拿到file返回的內容, 交給reader去合并
- reader 根據文件格式(yml) 轉為 map[string]interface{} 結構, 并進行覆蓋合并, 將結果存到對象變量上
- reader 處理完成后, config調用 file watcher 進行文件變更監(jiān)聽, 啟動協程監(jiān)聽
由此可見, config對象其實作為入口, 將數據生產交給file、env, 將數據加工解析交給 reader
代碼案例
init 接收外部參數定義解析配置文件地址
func init() {
flag.StringVar(&commonconf, "common", "./configs/local", "common config path, eg: -conf config.yaml")
flag.StringVar(&flagconf, "conf", "./configs/local/api", "config path, eg: -conf config.yaml")
flag.Parse()
}
使用config.New初始化文件配置
//初始化配置
//新增兩個配置源, 文件格式 common and flagconf 路徑
c := config.New(
config.WithSource(
file.NewSource(commonconf),
file.NewSource(flagconf),
),
)
// 關閉watch相關的監(jiān)聽器
defer c.Close()
// 加載配置文件
if err := c.Load(); err != nil {
panic(err)
}
//解析配置到bc結構上
var bc conf.Bootstrap
if err := c.Scan(&bc); err != nil {
panic(err)
}
我們看下config.New的實現
// 初始化解析器, 關聯reader對象, 數據交給由reader加工和存儲
func New(opts ...Option) Config {
o := options{
decoder: defaultDecoder,
resolver: defaultResolver,
}
for _, opt := range opts {
opt(&o)
}
return &config{
opts: o,
reader: newReader(o),
}
}
Options 有下面幾個屬性
type options struct {
sources []Source // 配置源, 由初始化負責傳入的source配置源
decoder Decoder // 解析器
resolver Resolver // 變量解析替換
}
執(zhí)行 Load 配置加載
func (c *config) Load() error {
// 因為我們在入口傳入的是file對象, 所以執(zhí)行src load的時候也是file對象的 load 方法
for _, src := range c.opts.sources {
// 獲取文件內容(可能是一個目錄, 會存在多個文件)
kvs, err := src.Load()
if err != nil {
return err
}
for _, v := range kvs {
log.Debugf("config loaded: %s format: %s", v.Key, v.Format)
}
// 合并配置key
if err = c.reader.Merge(kvs...); err != nil {
log.Errorf("failed to merge config source: %v", err)
return err
}
// 調用file watch, 監(jiān)聽文件變化
w, err := src.Watch()
if err != nil {
log.Errorf("failed to watch config source: %v", err)
return err
}
c.watchers = append(c.watchers, w)
// 異步監(jiān)聽文件變化(調用對應的watch對象)
go c.watch(w)
}
// 解析內容中是否包含 ${APPID:default} 變量
// 如果在配置文件中存在 APPID: xx 配置, 則進行替換
// 否則使用default默認值
if err := c.reader.Resolve(); err != nil {
log.Errorf("failed to resolve config source: %v", err)
return err
}
return nil
}
異步watch
func (c *config) watch(w Watcher) {
for {
kvs, err := w.Next()
if err != nil {
if errors.Is(err, context.Canceled) {
log.Infof("watcher's ctx cancel : %v", err)
return
}
time.Sleep(time.Second)
log.Errorf("failed to watch next config: %v", err)
continue
}
// 處理邏輯忽略 .....
c.cached.Range(func(key, value interface{}) bool {
k := key.(string)
v := value.(Value)
if n, ok := c.reader.Value(k); ok && reflect.TypeOf(n.Load()) == reflect.TypeOf(v.Load()) && !reflect.DeepEqual(n.Load(), v.Load()) {
v.Store(n.Load())
if o, ok := c.observers.Load(k); ok {
o.(Observer)(k, v)
}
}
return true
})
}
}
Scan 將配置轉換成結構體
var bc conf.Bootstrap
if err := c.Scan(&bc); err != nil {
panic(err)
}以上就是go kratos源碼及配置解析的詳細內容,更多關于kratos源碼配置的資料請關注腳本之家其它相關文章!
相關文章
Go?Web開發(fā)之Gin多服務配置及優(yōu)雅關閉平滑重啟實現方法
這篇文章主要為大家介紹了Go?Web開發(fā)之Gin多服務配置及優(yōu)雅關閉平滑重啟實現方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2024-01-01

