关于“凤凰官网”的折腾实录
兄弟们,今天得跟大家唠唠我最近搞的那个“凤凰官网”项目。这名字听着大气,但你真上手去碰,那简直就是一锅糊烂的浆糊,一团乱麻。我接手的时候,甲方那边就一句话:登录老是卡死,财务数据经常对不上,赶紧给我捋顺了。
我当时心想,不就是一个老旧的内部系统吗?能有多难搞?我以前什么烂摊子没收拾过?结果,我才刚把代码库拉下来,就开始骂娘了。
是环境。这“凤凰”系统不是一个东西,它是好几个小系统拼起来的。有十年前用Python写的核心模块,有五年前用Java搭起来的报表服务,还有最近两年新加的PHP接口。我光是配置起那堆依赖,就花了我整整两天时间。缺这个包,少那个库,版本冲突能把人逼疯。
捋代码:从头到尾摸了一遍
我没法直接上手修,因为我根本不知道问题出在哪儿。所以我决定先花大力气,把整个登录和数据流跑一遍。我从用户点击登录按钮开始,一步一步追踪:
- 我找到了前端的JS文件,发现登录校验逻辑写得非常混乱,光是加密算法就有三种。
- 我顺着请求摸到了那个Python写的后端服务。它不负责真正的认证,它只是个中转站。
- 我被带偏到了Java的认证服务,这个服务才是真正去数据库比对密码的。
- 更绝的是,数据同步竟然是通过一个每小时跑一次的定时任务,从MySQL拉到Oracle再拉回来的。中间丢包是常态。
这一趟摸下来,我算是明白了。这个系统根本就不是一家公司一个团队写出来的。这是在不同领导任期内,各个小组为了完成自己KPI,东拼西凑,各自为战的结果。
你问我为啥知道得这么清楚?因为我翻日志翻到一半,发现了一个我非常眼熟的注释。那是五年前,我还在上上家公司的时候,为了临时救急赶出来的一个小模块。当时我们团队人手不够,我一个人负责了那个月的认证接口优化,因为时间紧,我随手写了几行没来得及优化的代码,没想到这坨代码居然还在跑,而且成了整个系统的认证核心之一!
被逼着去“考古”和“扯皮”
意识到自己也是这烂摊子的“贡献者”之一后,我更不能忍了。我决心彻底搞定,不能让这块石头一直膈应着我。
我1去联系了当年的几个老同事。结果,搞Python的那位早就转行去卖保险了;写Java接口的那个,听说跳槽去了一家大厂,现在根本不接我的电话;唯一联系上的PHP小伙子,他也只知道他自己负责的那一小块,剩下的就撇清关系,说“跟我没关系,那是XX部门的事情”。
我感觉我不是在修Bug,我是在搞社会调研。没办法,我只能硬着头皮自己把数据库的表结构全盘摸了一遍,然后手工画出了整个数据流图。
最痛苦的是权限系统。用户登录进去后,卡顿的根源就在于它要调用至少五个不同的服务去判断你有没有查看某个报表的权限。每调用一次,就多耗费几秒钟。我尝试去优化,发现权限判断逻辑根本没法合并,因为它们用的数据源完全不一样。有的权限在Redis里,有的在配置文件里,有的干脆写死在代码里!
最终的实现和感悟
我没办法,只能采取最笨但最有效的办法:釜底抽薪,统一接口。我没有把那些老代码全部推倒重来,那不现实,时间也不允许。
我构建了一个统一的API网关,把所有乱七八糟的认证和权限校验,全部挪到网关层面去预先处理。我手动整理并合并了最常用的几种权限数据,牺牲了一点点灵活性,换来了巨大的效率提升。
- 我砍掉了那个每小时跑一次的数据同步任务,改成了实时推送,减少了数据滞后的问题。
- 我重构了登录接口,让它只调用一次核心认证服务,而不是五次。
- 我把之前自己写的那个核心模块也顺便优化了,算是了却了五年前的一个心病。
最终,“凤凰官网”终于跑起来了,登录速度从原来的平均十几秒,降到了两秒内。但这个过程也让我深深明白,一个复杂系统,一旦开始任由各个小团队随意堆砌,缺乏一个强有力的架构标准去约束,那么接盘的人,就只能像我这样,在历史遗留的烂泥里打滚。
我搞定这玩意儿,不是因为我技术有多高,而是因为我够轴,肯花时间去把那些没人愿意碰的陈年烂账,一个一个挖出来,再埋回去。