Golang

grpc-go源码分析之logger

从上个月开始梳理grpc-go的源码,希望从中学习到一些来自谷歌“原汁原味”的代码设计及风格。第一个开始分析的包是encoding,这个包下的代码行数不多,主要就是如下两个部分 encoding/decoding compress/decompress encoding/decoding是直接使用了第三方的包「protobuf规范的Go实现」,笔者没有继续深入梳理第三方包的代码。 compress/decompress是使用了Go SDK的compress包,笔者也并没继续往官方包的方向看代码。 所以对于grpc-go的encoding这个包,grpc-go本身并没有自己实现编码/解码,压缩/解压缩的代码,而是调用其他包。所以这个包也没什么代码值得去分析。不过值得一提的是笔者在看这个包的注释时候发现了一个错误,后来提了PR,reviewer当时跟我争辩了几句(他认为没有错)。然而,最终我的PR还是被合并啦! 接下来进入正题,开始分析第二个包grpclog。在梳理这个包的过程中,恰巧我准备从0开始为一个开源项目贡献Go-SDK。截止文章分享时,这个Go-SDK的logger部分我已经编写完成,设计的风格几乎与grpc的logger无异。毕竟,学以是为了致用 😀 通过源码可以知道loggerWrapper已经弃用,loggerT和tLogger是为了单元测试和基准测试用的,所以本文暂不讨论这三种struct(为行文流畅易读,struct在后面统称结构体)。 因此下文主要从以下三点分析: glgger结构体 componentData结构体 初始化流程 glogger结构体 梳理所有grpc-go打印日志的方法(除了测试用的实现方法)会发现:尽管一些方法所属的结构体并不是glogger(一些是下面的componentData),但调用链最终还是会到glogger结构体所属的方法。最后,glogger结构体的方法使用了第三方包“glog”输出日志。 glog是谷歌在github上开源的日志类项目 通过梳理这些结构体的实现方法,还能发现duck-typing这种设计思想在Go语言中的使用,深深体验到这种简洁的设计风格所带来的便利性。简单来说就是当一个结构体的实现了一个接口的所有方法,那么这个结构体就实现了这个接口。以grpc-go举例说明: componentData结构体 首先,可以从componentData结构体实现的方法看出:它同样了LoggerV2接口,如下图: 以componentData结构体的InfoDepth方法举例,该方法作用主要有两点: 在每行日志前拼接调用该方法的微服务名称; 将指定的日志打印栈深度+1。 实际上大部分微服务的都是通过调用Info方法(指定了日志打印栈深度为1),来调用InfoDepth: 最后internal包里的方法会判断是否初始化了变量DepthLogger去执行真正输出日志的方法。至于变量DepthLogger是如何被初始化的,会在第三部分“初始化流程”中分析。先提前说明:这里被初始化进去的正是glogger结构体,所以最终由第三方包“glog”输出日志。 初始化流程...

Continue reading...

在阳春三月,开启一段新的学习之旅

在今年春节结束之际,给自己订了学习计划:包括阅读一些书籍和在线课程,其目的是为了提高Go的技术水平。昨天,学习进度到了这项计划的里程碑——50%,而我毅然决然地放弃了之前的计划,花了约一天的时间说服自己制定新的计划并开启一段新的学习之旅。 文章接下来的内容会记录昨天思想斗争的片段,供未来回首。若对正在阅读此篇文章的你有帮助/启发,那真是笔者莫大的荣幸。若跟你的观点相悖,忽略以下内容即可。 从Java工程师转到Go工程师已经过去五个月(对于非程序员读者可以这样理解:从英语翻译员转到法语翻译员),现在笔者自认为处在初/中Go工程师的水平。如果按照之前订下的计划继续学习,再花几个月的时间也仅是横向扩展了知识面,对于Go语言的深度认知还会是欠缺的状态,这跟我想达到的目标不一致。 笔者不想再踩下以前学习Java的坑:“对于一个编程语言本身的设计思想,官方标准库的方法以及其它等等基础知识还没熟练掌握,就开始学习各种框架,第三方中间件的使用“。这虽然有益于快速上手企业的业务代码开发,可无益于做一个编程风格优秀的程序员,也很难在各大论坛/社区与其他优秀的程序员“对线”。 “愿意花时间横向扩展,而不愿意花时间纵向深究知识“这种现象的产生我认为一部分来自于各大企业的招聘需求,希望求职者什么技能都掌握。其实能猜到企业会将愿意将大部分投入放到招聘业务开发的程序员,毕竟业务开发直接与收入挂钩。现在还真没有勇气在简历上用“精通A”替换“掌握A, B, C”,因为在各招聘网站上发布的职位还是以业务开发的多,负责框架/中间件/容器等这类专项研发的职位相对少些。 也许很多人(至少我以前就是)就会用这些招聘需求来决定自己的学习方向,花了很多精力做知识面的横向扩展,希望在和别人聊到某项技术的时候,自己多多少少能接得上话题。这也为接下来我要聊的内容做个铺垫: “面向企业编程”还是“面向兴趣编程” 目标 做好自己的兴趣,总会有欣赏你的人/企业? 自己的未来应该由自己决定 “面向企业编程“还是“面向兴趣编程” 这个问题放在三年前刚毕业的时候,毫无疑问我会选择“面向企业编程”,因为当时还不明确自己的目标。说实话,我现在选择“面向兴趣编程”还是会有一丝担心,毕竟当大部分人还是选择“面向企业编程”,对于那些在人潮中逆行的人来说应该都会有怀疑自己的时候。 企业的职位需求可以作为参考之一,但不应该为你的学习/发展方向做决定。这是我现在践行的学习/发展方式,至于我的选择是不是最优解,就留给时间来证明吧。 目标 人的时间都是有限的,所以得根据目标对时间进行取舍。如果你的目标是成为首富,那可能要将更多的时间留给赚钱;如果你的目标是成为大多数企业都青睐的对象,那可能要将更多的时间花在学习企业的需求。 对于完成我自己的目标,可以允许我把更多的时间放在我的兴趣上(我的兴趣现在就是精通Go,包括设计思想,标准库方法等)。我认为在IT行业中,细分到某一专业领域,如果你对这一领域很感兴趣,只要你的水平在第一梯队中。我觉得收入也不会比其他热门专业领域少很多,至少应该能过上相对自在的生活。虽然收入相对没那么多,但是过得自在、快活。 显然,我不是要做赚最多钱的程序员,是想做个喜欢编程的程序员。 做好自己的兴趣,总会有欣赏你的人/企业? 其实这个小标题我的答案也不确定,但很多文章/故事给出来的答案总是积极的。我想,在IT行业中,做好自己的兴趣,应该不会失业,即使失业也不会为一日三餐发愁吧? 自己的未来应该由自己决定 现在有很多IT行业的大佬为分享自己的经历,不妨一看,但无法也不能照抄。可以作为参考,然后制定一个自己的目标和一份成长规划。即便以后没能实现自己的目标,也不会埋怨自己照抄了别人的人生规划。: -D 其实我觉得,只要是一个态度积极的人并且认真的做了分析和计划,即便没实现目标,也不会差到哪里去。 最后,分享一下我新的学习之旅将从《The...

Continue reading...

结束Java工程师生涯,往新蓝海出发

一周前我入职了新公司,不再以Java工程师的身份。做出这个决定的难度可比写下这篇“看似吸引”的标题的难度大多了。除了想借此篇文章对上一份工作做一次总结,也想为自己留一份“记录”,用以回首这个职业生涯,甚至可能是人生的转折点。

Continue reading...