我当初接手这块东西的时候,脑袋里是一团浆糊。我得承认,我们公司的系统,尤其是那个叫“鲁迪”的后台框架,简直就是个历史遗留的大坑。我们一直以为,按着文档来,跑的应该是5.2版本,可这几个月来,我们只要一做功能迭代,线上环境就跟闹鬼了一样,各种报错,各种数据对不上。
我怎么开始扒拉这个“鲁迪”的?
上个月,我们老大急眼了。一个客户的重要接口突然挂了,损失不小。所有的开发都说代码没问题,测试也说跑得好好的。但生产环境就是搞不定。当时所有人都在那里争吵,互相甩锅,那场面,简直比菜市场还热闹。我当时就坐不住了,拍着桌子说,别吵了,我来摸一下,看看到底是哪里的版本没对齐。
我的实践记录,就是从这里拉开序幕的。
我第一步做的,就是登录到我们所谓的“标准”预发布环境。大家都说这个环境是干净的,和生产环境配置一样。我先是找到了“鲁迪”的启动脚本。我翻开脚本,想从里面直接瞄一眼版本号。结果?脚本里面引用了一个环境变量,写着:RUDY_VERSION=${CONFIG_V}。好家伙,又是个套娃,根本没有写死!
我马上去查了环境配置文件,那个配置文件老长了,密密麻麻的。我用尽了各种搜索关键词,什么version,什么V,什么Rudy。终于定位到了一行配置:CONFIG_V=LATEST_STABLE。这下我彻底懵了,什么是LATEST\_STABLE?这完全是凭感觉瞎写!
深挖代码库,找出真相
光看部署环境是没戏了。我当时就决定,得去查代码库,而且是那种没人敢动的、最底层的基础库。
- 第一件干的事:我打开了内部的Git仓库,专门定位到“鲁迪”的基础服务代码分支。
- 第二件干的事:我翻找了核心模块的构建日志。这个构建日志平时没人看,它记录了每次打包时,系统自己认定的版本信息。
我花了一整个下午,翻阅了上百条构建记录。我发现了一个非常吊诡的事情:最近一个月,虽然开发分支一直推的都是5.2的功能,但是构建系统在拉取依赖的时候,每次都拉了一个老旧的4.8.3版本的依赖库进去。
我当时的心情,就像是被雷劈了一样。为什么会这样?我马上去问了几个老同事。他们说,这个构建脚本是三年前老李写的,老李辞职的时候没交接大家都以为它能自动更新,结果它里面写死了一个拉取旧版本的命令,只因为那个旧版本的文件名比较短,写起来方便!
简直是荒唐!就是因为一个文件名短,整个公司都在为这个4.8.3版本买单,所有新的功能都因为底层环境不匹配而折腾来折腾去。
实现:强制升级与善后
搞清楚了真相后,我的工作重心立刻转移了。
我没有直接跑去骂人,我知道骂人没用。我立刻开始着手清理这个构建脚本。我删除了那个指向旧版本依赖的鬼指令,然后硬是在构建脚本里加了一个版本校验的步骤。
我的核心步骤是这样的:
- 第一步:制定了新的版本规范,不再用什么LATEST\_STABLE这种模糊的字眼,必须使用固定的数字版本,比如5.2.1。
- 第二步:我联系了运维团队,申请了专门的窗口期,把预发布和生产环境的“鲁迪”服务全部停掉。
- 第三步:我手动编译了一个全新的5.2.1版本的镜像,然后替换掉了线上所有的旧镜像。
整个过程折腾了十几个小时,中间各种依赖报错,各种配置文件不匹配。我不断地调整,不断地重启。我甚至自己写了个小工具,专门扫描生产环境,确保所有部署点的版本号都是5.2.1,而不是那个祖宗级别的4.8.3。
当所有服务都跑起来,并且各项新功能测试通过的时候,我才松了口气。“鲁迪”的最新版本是多少?对外,我们说我们升级到5.2.1了。但在我心里,最新的版本是“没坑的版本”。
这事儿也给我一个教训:任何被忽视的细节,都会变成一个大麻烦,等着你来收拾。这也是我为什么这么喜欢记录这些实践过程的原因,因为只有自己亲手扒开来看,才能知道下面到底藏了多少陈年烂泥。