go kratos源码及配置解析

 更新时间:2022年12月05日 11:57:55   作者:小宇渣渣渣  
这篇文章主要为大家介绍了go kratos源码及配置解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

相关类图

项目启动时一般前置条件为解析配置文件, 我们看下这块是怎么设计的.

流程解释

  • config 实现 config Interface 接口, 初始化reader对象
  • 调用Load方法, 通过入口注入的不同文件源, 调用实现了source interface 对应的Load方法(以file举例子)
  • file 通过 Load 入口, 判断是目录还是文件, 执行对应的方法, 拿到文件内容返回
  • config 拿到file返回的内容, 交给reader去合并
  • reader 根据文件格式(yml) 转为 map[string]interface{} 结构, 并进行覆盖合并, 将结果存到对象变量上
  • reader 处理完成后, config调用 file watcher 进行文件变更监听, 启动协程监听

由此可见, 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相关的监听器
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 // 变量解析替换
}

执行 Load 配置加载

func (c *config) Load() error {
    // 因为我们在入口传入的是file对象, 所以执行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, 监听文件变化
		w, err := src.Watch()
		if err != nil {
			log.Errorf("failed to watch config source: %v", err)
			return err
		}
		c.watchers = append(c.watchers, w)
        // 异步监听文件变化(调用对应的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源码配置的资料请关注脚本之家其它相关文章!

相关文章

  • Golang中HTTP路由设计的使用与实现

    Golang中HTTP路由设计的使用与实现

    这篇文章主要介绍了Golang中HTTP路由设计的使用与实现,为什么要设计路由规则,因为路由规则是HTTP的请求按照一定的规则 ,匹配查找到对应的控制器并传递执行的逻辑,需要的朋友可以参考下
    2023-05-05
  • go货币计算时如何避免浮点数精度问题

    go货币计算时如何避免浮点数精度问题

    在开发的初始阶段,我们经常会遇到“浮点数精度”和“货币值表示”的问题,那么在golang中如何避免这一方面的问题呢,下面就跟随小编一起来学习一下吧
    2024-02-02
  • golang 40行代码实现通用协程池

    golang 40行代码实现通用协程池

    golang协程机制很方便的解决了并发编程的问题,但是协程并不是没有开销的,所以也需要适当限制一下数量。这篇文章主要介绍了golang 40行代码实现通用协程池,需要的朋友可以参考下
    2018-08-08
  • jenkins配置golang 代码工程自动发布的实现方法

    jenkins配置golang 代码工程自动发布的实现方法

    这篇文章主要介绍了jenkins配置golang 代码工程自动发布,jks是个很好的工具,使用方法也很多,我只用了它简单的功能,对jenkins配置golang相关知识感兴趣的朋友一起看看吧
    2022-07-07
  • golang 如何删除二进制文件中的源码路径信息

    golang 如何删除二进制文件中的源码路径信息

    这篇文章主要介绍了golang 如何删除二进制文件中的源码路径信息,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • Go语言学习之WaitGroup用法详解

    Go语言学习之WaitGroup用法详解

    Go语言中的 WaitGroup 和 Java 中的 CyclicBarrier、CountDownLatch 非常类似。本文将详细为大家讲讲WaitGroup的用法,感兴趣的小伙伴可以跟随小编一起学习一下
    2022-06-06
  • Go语言基础函数包的使用学习

    Go语言基础函数包的使用学习

    本文通过一个实现加减乘除运算的小程序来介绍go函数的使用,以及使用函数的注意事项,并引出了对包的了解和使用,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • golang time常用方法详解

    golang time常用方法详解

    这篇文章主要介绍了golang time常用方法详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • golang占位符%v、%+v、%#v举例详解

    golang占位符%v、%+v、%#v举例详解

    这篇文章主要给大家介绍了关于golang占位符%v、%+v、%#v的相关资料,Go语言中的占位符通常用于格式化输出,它们以%开头,后跟一个字符,表示要转换的数据类型,需要的朋友可以参考下
    2024-05-05
  • 详解Golang中Context的原理和使用技巧

    详解Golang中Context的原理和使用技巧

    Golang 的 Context 包,中文可以称之为“上下文”,是用来在 goroutine 协程之间进行上下文信息传递的,这些上下文信息包括 kv 数据、取消信号、超时时间、截止时间等。本文主要介绍了Context的原理和使用技巧,希望对大家有所帮助
    2022-11-11

最新评论