Golang之服务配置自动初始化

2019-04-24 16:28:38

背景

今天分享一个利用reflect在实际项目中比较省时、代码简洁且高效的方法-服务配置自动初始化的方法。
我们在起一个Web项目时,常常都是直接使用开源的一些框架或组建,然后在我们自己的项目中要使用之前按照该框架或组建提供的帮助文档一个一个进行相应的初始化配置。也许我们只引用其中一两个,这样写都还能忍受,可是如果这个服务会引用更多的呢?
自行脑补

效果

1

  1. 代码简洁化
  2. 接入第三方库就如搭积木一样,模块化,随取随用
  3. 可维护性高

干货

下面,我们就来利用reflect实现该功能。

思路

磨刀不误砍柴工,我们先整理好一个简单思路,然后再尝试实现它,这样就简单了。

  • 从远端配置服务或本地获取到我们需要初始化的配置
  • 解析配置中的数据
  • 判断配置中元素是否有实现我们指定方法,如果有就执行它,没有就跳过
    没错,用语言描述就这么三句话,就这么简单。

获取配置

服务要启动,获取配置要么从远端配置服务拉取,要么从本地读取,就以常见的json格式作为我们本次举例的配置格式吧。

{
    "ginx": {
        "listen_port": 8080
    },
    "conn_timeout":2
}

既然是json化的配置,那我们就需要一个struct结构体来对配置进行反解析,这个貌似没什么好说的。

type Cfg struct {
	ConnTimeout int        `json:"conn_timeout"`
	Ginx        *ginx.Ginx `json:"ginx"`
	// other config
}

其中ginx.Ginx是我们自定义的一个结构体。

查找结构体中是否包含某方法

type ICanInit interface {
	Init()
}

func InitialRoot(rv reflect.Value) {
	tpe := rv.Type()
	for i := 0; i < tpe.NumField(); i++ {
		value := rv.Field(i)
		if conf, ok := value.Interface().(ICanInit); ok {
			conf.Init()
		}
	}
}

对,上面的这个就是判断某结构体中是否已实现Init()方法,有的话就执行它。这个就是实现这个功能的核心,是不是很简单?哈哈。
我们在实现这个功能之前,只需要对配置结构体进行一下简单的类型判断就OK了。

总结

reflect的用处远不止于此,多总结,然后付诸行动。

如有兴趣,源码在此

201904读书会

《永乐大帝朱棣》 状态:100% finished 毛佩琦的一本老书,断断续续看完差不多前后花了有两个月。历朝历代,君王上纲上线要么子承父业,要么是抢过来的。朱棣也不例外,朱棣是洪武帝的第四个儿子,也是朱元璋最喜欢的一个儿子,能打仗,有谋略,敢下手,缺偏偏因历史原因需要将太子传给儿子中的老大朱标,朱标因年早逝又传给世子朱允炆,抢夺帝位就此开始。 建文元年,朱允炆主张仁治,在黄子澄等一干人帮助下进行了削藩,这就成功触碰到了朱棣的神经,生死存亡,于是打起了靖难的旗号起兵反抗,起兵过程中往往应征了运气也是实力的一部分,在老天爷多次帮忙下活了过来且越来越壮大,最终如常所愿。一幕幕的战争场面也能实时的映入眼帘。 一朝天子一朝臣,新帝上任,旧臣下课(往往是被诛杀),同朱元璋称帝一样,作为皇帝往往为了免除后患,都会大肆进行杀戮,这就是朝廷和政治的斗争,为财为权,不管经历多少年,这都是利益使然,如今社会也一样。 朱允炆从此开始了十六年的逃亡生活,隐姓埋名,却成了朱棣的一大心病,因为活不见人死不见尸,这个后患一直未被根除。直到自己快寿终前才得知朱允炆的去世,了却了心愿。 朱棣这个人,不能说好,也不能说坏,

【译】调试使用Go1.12开发部署的程序

源地址:https://blog.golang.org/debugging-what-you-deploy 1. 介绍 Go 1.11和Go 1.12在允许开发人员调试对已部署至生成环境的二进制可执行程序方面取得了重大进展。 由于Go编译器在生成更快的二进制文件方面变得越来越积极,我们在可调试性方面已失去了优势。在Go 1.10中,用户在编译时完全禁用编译优化,才能在使用Delve等交互式工具中获得良好的调试体验。但是用户不应该为了可调试性而降低程序性能,尤其是在生产环境中。如果在生产环境了出现了问题,且需要在生产环境进行debug调试,我们不应该采用未经调优的二进制文件直接放到生产环境中。 对于Go 1.11和1.12,我们专注于提升对已经编译优化后的二进制文件的debug体验(Go编译器的默认设置),改进包括: 更准确的入参(value)检测,特别是function的入参; 更精确的识别语句边界,以便一步一步调试时不那么跳跃,断点能更多的落在调试人员期望的地方; Delve调用Go函数的初步支持(goroutines以及垃圾回收机制使得它比C和C++更复杂) 2. 使用Delve调试优化代码 Delve是基于x86的,支持Linux和MacOS。Delve对Go的goroutines结合比较好,也支持Go的其他功能,能有比较好的调试体验。Delve也是Goland、