Go技巧 - 保障排查问题时的代码一致性
当我们排查复杂的线上问题时,往往需要结合开发环境的代码进行分析。但是,很多问题排查到最后,却发现线上和本地的代码是不一致的,浪费了大量时间。
那么,就让我们从整个代码发布的链路来分析会有哪些常见的坑。这里,我以Go
语言以及主流的git
、Docker
、Kubernetes
系统为例。
1 本地的脏代码
线上问题往往发生在需求迭代过程中,我们本地环境还在开发过程中,有相当一部分的“脏代码” - 它们或者没有提交commit
,或者没有推送到远端push
。
这时,基于这些“脏代码”排查的问题很容易得出错误的结果。所以,一般建议 将发布分支和开发分支隔离,在排查时进行切换。
2 切换分支异常
一般发布到线上的代码都会指定分支,比如master
,而排查问题时就切换到对应的分支。那这个简单的切换过程会出现问题吗?会,而且我就遇到过多次,常见的包括2种:
- 切换分支失败。一般是由于当前分支有未
commit
的内容,切换时发生冲突 - 切换后没有拉取最新代码。本地的
master
落后于代码库中的最新版本。
3 线上版本并不是最新版本
为了提升研发效率,建议将线上版本与发布分支的最新版本保持一致。这样,用户就无需去查看线上的版本号,而是直接切换到对应分支的最新版本即可。
但是,从代码仓到线上经过了CICD流水线,并不一定能保证一致:
- 上次发布失败了,线上的仍是老版本
- 线上版本发生了回退,但代码库没有回滚
这类问题发生的频率也不低,值得我们关注。
4 Go语言开发版本与编译版本不一致
尽管Go
语言的兼容性很好,但不同版本之间的差异还是存在的,并且发生问题时往往很隐蔽。
我们在维护本地Go
语言版本时,一定要优先保证与编译所使用的版本。
如果你想尝试某些新版本的特性,也不要覆盖当前版本,而是更换新版本默认的安装路径。
5 vendor的依赖库问题
Go
语言的版本依赖方案已经由Go Module
实现大一统了,而传统的vendor
方案很容易出现各种奇怪的问题。
例如,我曾遇到过一个问题:有人修改了vendor
目录中的依赖代码,但在编译环境时,会通过go mod vendor
命令更新依赖,导致修改的内容被替换,造成了和预期不一致的内容。
6 编译环境的问题
Go
语言的编译环境也可能遇到一些奇怪的问题:有的因为设置环境变量GOOS
、GOARCH
等参数影响编译输出,有的因为引入Cgo
而对相关内容有依赖。
所以,编译环境一定要尽量简单、采用原始的操作系统,相关依赖(如环境变量)用命令行的方式输入,而不要隐藏在机器环境中。从这一点看,用Docker
容器的优势就非常明显了。
小结
随着公司基础平台的完善,保障排查问题时的代码一致性 这个问题会越来越简单,但依然会发生问题。
通过这个话题,希望大家对自己的程序有进一步了解:你的代码是怎么发布到线上的?这个过程中会有什么坑?
编程思考 - 在日常开发工作中融入项目管理思维
目前,许多公司里的专职“项目经理”角色越来越少,往往仅在大型项目中才能看到。
导致这个现象的原因,并不是项目管理不重要;相反地,而是项目管理的重要性已经深入到每个开发者的心中,人人都应该是自己的项目经理。在小型项目中,往往会由资深的技术负责人兼任项目管理的角色。
作为普通开发者,我们在日常开发中,其实已经接触到项目管理的一些内容了,如:
- 项目范围管理 - 确认需求交付的范围
- 项目成本管理 - 估算需求投入的人力和时间
- 项目进度管理 - 统计与汇报当前的需求进度
- 项目风险管理 - 遇到风险点时,向领导沟通或采用备用方案
这些相关的工作串联起来,就是一个简单的项目管理,只是不够体系化。当有合作开发的机会时,我们可以多观察其他经验丰富的同事或专职的项目经理,学习他们的项目管理方式,选择性地采用。
工作生活 - 给生活穿插一些挑战
我和绝大多数人一样,倾向于“躺平式”的生活;但我也知道,生活充满变化,过度躺平在未来抗风险能力会很差。在面对高度不确定性的未来时,我很容易陷入焦虑。
为了增强自己面对“危机”的能力,我会给自己的生活增加一些挑战,如:
- 写一篇长文
- 跑一次半马
- 考一个证书
这些目标很明确、难度不高,也不会要求自己做得多好。对我个人来说,这些挑战能增强自己面对挑战时的精神“肌肉”,就已达到目标了。
Github: https://github.com/Junedayday/code_reading
Blog: http://junes.tech/
Bilibili: https://space.bilibili.com/293775192
公众号: golangcoding